private async Task <IList <ServiceLocationMsg> > GetTopServiceLocationMessages( [NotNull] DiscoverServicesRequest request) { List <ServiceLocation> allServices = GetServices(request); _logger.LogDebug("{count} {serviceName} service(s) found in service registry:", allServices.Count, request.ServiceName); if (allServices.Count == 0) { return(new List <ServiceLocationMsg>(0)); } ServiceEvaluator serviceEvaluator = new ServiceEvaluator(ServiceComparer, _channels, _clientCertificate); var qualifiedServices = await serviceEvaluator.GetLoadQualifiedServices(allServices, WorkerResponseTimeout); if (qualifiedServices.Count == 0) { // Try again with very high time-out: qualifiedServices = await serviceEvaluator.GetLoadQualifiedServices(allServices, TimeSpan.FromSeconds(30)); } _logger.LogDebug("{serviceCount} service location(s) responded with a load report.", qualifiedServices.Count); if (qualifiedServices.Count == 0) { return(new List <ServiceLocationMsg>(0)); } IList <QualifiedService> orderedServices = serviceEvaluator.Prioritize(qualifiedServices); ExcludeRecentlyUsed(orderedServices); int maxResultCount = request.MaxCount == 0 ? -1 : request.MaxCount; IList <ServiceLocationMsg> result = UseTopServices(orderedServices, maxResultCount).ToList(); return(result); }
private async Task <IList <ServiceLocationMsg> > GetHealthyServiceLocationMessages( [NotNull] DiscoverServicesRequest request) { // By default the prioritization should be random rather than the order defined in the // service registry. TODO: Configurable prioritization: // Random (using shuffled services) // Round-robin (using least-recently-used list) and based on available / best services List <ServiceLocation> allServices = GetServices(request, true); _logger.LogDebug("{count} {serviceName} service(s) found in service registry:", allServices.Count, request.ServiceName); if (allServices.Count == 0) { return(new List <ServiceLocationMsg>(0)); } ServiceEvaluator serviceEvaluator = new ServiceEvaluator(ServiceComparer, _channels, _clientCertificate); ConcurrentBag <QualifiedService> services = await serviceEvaluator.GetHealthyServiceLocations(allServices, WorkerResponseTimeout, request.MaxCount); foreach (QualifiedService qualifiedService in services) { if (RemoveUnhealthyServices && !qualifiedService.IsHealthy) { var unhealthyLocation = qualifiedService.ServiceLocation; _serviceRegistry.EnsureRemoved(unhealthyLocation.ServiceName, unhealthyLocation.HostName, unhealthyLocation.Port, unhealthyLocation.UseTls); } } return(ToServiceLocationMessages(services .Where(qs => qs.IsHealthy) .Select(qs => qs.ServiceLocation)).ToList()); }