예제 #1
0
 internal string GetAllHosts()
 {
     lock (_lock)
     {
         return(string.Join(", ", ReachableHosts.Concat(UnreachableHosts).Select(h => h.HostName)));
     }
 }
예제 #2
0
        /// <summary>
        /// Loads the specified settings, overwriting existing settings.
        /// </summary>
        /// <param name="updatedEndPointsResult"></param>
        /// this <see cref="RemoteHostPool"/>.
        /// <exception cref="ArgumentNullException">Thrown when </exception>
        /// <exception cref="EnvironmentException"></exception>
        private void ReloadEndpoints(EndPointsResult updatedEndPointsResult)
        {
            lock (_lock)
            {
                try
                {
                    var updatedEndPoints = updatedEndPointsResult.EndPoints;
                    if (updatedEndPoints.Any() == false)
                    {
                        Health.SetHealthFunction(() =>
                        {
                            var config = GetConfig();
                            if (IsHealthCheckSuppressed(config))
                            {
                                return(HealthCheckResult.Healthy($"No endpoints were discovered from source '{config.Source}' but the remote service was not in use for more than {config.SuppressHealthCheckAfterServiceUnused?.TotalSeconds} seconds."));
                            }
                            else
                            {
                                return(HealthCheckResult.Unhealthy($"No endpoints were discovered from source '{config.Source}'."));
                            }
                        });

                        EndPointsResult = updatedEndPointsResult;

                        ReachableHosts   = new List <RemoteHost>();
                        UnreachableHosts = new List <RemoteHost>();
                    }
                    else
                    {
                        if (EndPoints != null)
                        {
                            foreach (var removedEndPoint in EndPoints.Except(updatedEndPoints))
                            {
                                ReachableHosts.SingleOrDefault(h => h.Equals(removedEndPoint))?.StopMonitoring();
                                ReachableHosts.RemoveAll(h => h.Equals(removedEndPoint));
                                UnreachableHosts.RemoveAll(h => h.Equals(removedEndPoint));
                            }
                        }

                        var newHosts = updatedEndPoints
                                       .Except(EndPoints ?? Enumerable.Empty <EndPoint>())
                                       .Select(ep => new RemoteHost(ep.HostName, this, _lock, ep.Port));

                        ReachableHosts.AddRange(newHosts);

                        EndPointsResult = updatedEndPointsResult;
                        Counter         = (ulong)_random.Next(0, ReachableHosts.Count);

                        Health.SetHealthFunction(CheckHealth);
                    }
                }
                catch (Exception ex)
                {
                    Log.Warn("Failed to process newly discovered endpoints", exception: ex);
                    Health.SetHealthFunction(() => HealthCheckResult.Unhealthy("Failed to process newly discovered endpoints: " + HealthMonitor.GetMessages(ex)));
                }
            }
        }
예제 #3
0
 private Dictionary <string, string> HealthData()
 {
     lock (_lock)
     {
         return(new Dictionary <string, string>
         {
             { "ReachableHosts", string.Join(",", ReachableHosts.Select(_ => _.HostName)) },
             { "UnreachableHosts", string.Join(",", UnreachableHosts.Select(_ => _.HostName)) }
         });
     }
 }
예제 #4
0
 public void Dispose()
 {
     lock (_lock)
     {
         EndPointsChangedBlockLink.Dispose();
         foreach (var host in ReachableHosts.Concat(UnreachableHosts).ToArray())
         {
             host.StopMonitoring();
         }
         ReachabilityBroadcaster.Complete();
         DiscoverySource.Dispose();
         Health.Dispose();
     }
 }
예제 #5
0
        internal bool MarkUnreachable(RemoteHost remoteHost)
        {
            lock (_lock)
            {
                if (ReachableHosts.Remove(remoteHost))
                {
                    if (ReachableHosts.Count == 0)
                    {
                        ReachabilityBroadcaster.Post(new ServiceReachabilityStatus {
                            IsReachable = false
                        });
                    }
                    UnreachableHosts.Add(remoteHost);
                    return(true);
                }

                return(false);
            }
        }
예제 #6
0
        internal bool MarkReachable(RemoteHost remoteHost)
        {
            lock (_lock)
            {
                if (UnreachableHosts.Remove(remoteHost))
                {
                    ReachableHosts.Add(remoteHost);
                    if (ReachableHosts.Count == 1)
                    {
                        ReachabilityBroadcaster.Post(new ServiceReachabilityStatus {
                            IsReachable = true
                        });
                    }

                    FirstAvailableHostCompletionSource?.SetResult(remoteHost);
                    FirstAvailableHostCompletionSource = null;

                    return(true);
                }

                return(false);
            }
        }