Ejemplo n.º 1
0
        public LoadBalancer(
            IDiscovery discovery,
            DeploymentIdentifier deploymentIdentifier,
            ReachabilityCheck reachabilityCheck,
            TrafficRoutingStrategy trafficRoutingStrategy,
            Func <Node, DeploymentIdentifier, ReachabilityCheck, Action, NodeMonitoringState> createNodeMonitoringState,
            Func <string, AggregatingHealthStatus> getAggregatingHealthStatus,
            Func <DiscoveryConfig> getConfig,
            IDateTime dateTime,
            ILog log,
            IEnvironment environment
            )
        {
            DeploymentIdentifier      = deploymentIdentifier;
            Discovery                 = discovery;
            ReachabilityCheck         = reachabilityCheck;
            TrafficRoutingStrategy    = trafficRoutingStrategy;
            CreateNodeMonitoringState = createNodeMonitoringState;
            GetConfig                 = getConfig;
            DateTime       = dateTime;
            _lastUsageTime = DateTime.UtcNow;
            Log            = log;
            var    aggregatingHealthStatus = getAggregatingHealthStatus(deploymentIdentifier.ServiceName);
            string healthCheckEntryName    = (deploymentIdentifier.DeploymentEnvironment ?? "prod") + deploymentIdentifier.Zone == environment.Zone ? "" : $" ({deploymentIdentifier.Zone})";

            _healthCheck = aggregatingHealthStatus.Register(healthCheckEntryName, CheckHealth);
        }
Ejemplo n.º 2
0
        public NewServiceDiscovery(string serviceName,
                                   ReachabilityCheck reachabilityCheck,
                                   IEnvironment environment,
                                   ISourceBlock <DiscoveryConfig> configListener,
                                   Func <DiscoveryConfig> discoveryConfigFactory,
                                   ILog log,
                                   IDiscovery discovery,
                                   Func <string, AggregatingHealthStatus> getAggregatingHealthStatus)
        {
            Log          = log;
            _discovery   = discovery;
            _serviceName = serviceName;

            _originatingEnvironmentDeployment = new DeploymentIdentifier(serviceName, environment.DeploymentEnvironment, environment);
            _masterDeployment = new DeploymentIdentifier(serviceName, MASTER_ENVIRONMENT, environment);

            _reachabilityCheck = reachabilityCheck;
            GetConfig          = discoveryConfigFactory;

            _initTask        = Task.Run(() => ReloadRemoteHost(discoveryConfigFactory()));
            _configBlockLink = configListener.LinkTo(new ActionBlock <DiscoveryConfig>(ReloadRemoteHost));

            AggregatingHealthStatus = getAggregatingHealthStatus("Discovery");
            _healthCheck            = AggregatingHealthStatus.RegisterCheck(_serviceName, () => new ValueTask <HealthCheckResult>(_getHealthStatus()));
            _getHealthStatus        = () => HealthCheckResult.Healthy("Initializing. Service was not discovered yet");
        }
Ejemplo n.º 3
0
 public void Setup()
 {
     _log       = (LogSpy)_kernel.Get <ILog>();
     _discovery = Substitute.For <IDiscovery>();
     _discovery.GetNodes(Arg.Any <DeploymentIdentifier>()).Returns(_ => Task.FromResult(_getSourceNodes()));
     _reachabilityCheck = (n, c) => throw new EnvironmentException("node is unreachable");
     _environment       = Substitute.For <IEnvironment>();
 }
Ejemplo n.º 4
0
 public NodeMonitoringState(Node node, DeploymentIdentifier deploymentIdentifier, ReachabilityCheck reachabilityCheck, Action reachabilityChanged, ILog log)
 {
     Node = node;
     DeploymentIdentifier = deploymentIdentifier;
     ReachabilityCheck    = reachabilityCheck;
     ReachabilityChanged  = reachabilityChanged;
     Log = log;
 }
Ejemplo n.º 5
0
        public async Task GetNode_NodesUnreachableButReachabilityCheckThrows_ErrorIsLogged()
        {
            CreateLoadBalancer();
            SetupDefaultNodes();
            var reachabilityException = new Exception("Simulated error while running reachability check");

            _reachabilityCheck = (_, __) => throw reachabilityException;
            await Run20Times(node => _loadBalancer.ReportUnreachable(node));

            await Task.Delay(1500);

            _log.LogEntries.ToArray().ShouldContain(e => e.Exception == reachabilityException);
        }
Ejemplo n.º 6
0
        public async Task GetNode_NodeIsReachableAgain_NodeWillBeReturned()
        {
            CreateLoadBalancer();
            SetupDefaultNodes();

            var selectedNode = await _loadBalancer.TryGetNode();

            _loadBalancer.ReportUnreachable(selectedNode);

            (await Get20Nodes()).ShouldNotContain(selectedNode);

            _reachabilityCheck = (_, __) => Task.FromResult(true);
            await Task.Delay(1000);

            (await Get20Nodes()).ShouldContain(selectedNode);
        }
Ejemplo n.º 7
0
        public MultiEnvironmentServiceDiscovery(string serviceName, IEnvironment environment, ReachabilityCheck reachabilityCheck,
                                                IDiscovery discovery, Func <DiscoveryConfig> getDiscoveryConfig, Func <string, AggregatingHealthStatus> getAggregatingHealthStatus,
                                                IDateTime dateTime)
        {
            _healthStatus      = new HealthMessage(Health.Info, message: null, suppressMessage: true);
            ServiceName        = serviceName;
            Environment        = environment;
            ReachabilityCheck  = reachabilityCheck;
            Discovery          = discovery;
            GetDiscoveryConfig = getDiscoveryConfig;
            DateTime           = dateTime;
            _lastUsageTime     = DateTime.UtcNow;
            var aggregatingHealthStatus = getAggregatingHealthStatus(serviceName);

            _healthCheck = aggregatingHealthStatus.Register(Environment.DeploymentEnvironment, CheckHealth);
        }
Ejemplo n.º 8
0
        public async Task GetNode_AllNodesUnreachableThenAllNodesReachable_ReturnsAllNodes()
        {
            CreateLoadBalancer();
            SetupSourceNodes(_node1, _node2, _node3);
            await Run20Times(node => _loadBalancer.ReportUnreachable(node));

            Should.Throw <EnvironmentException>(() => _loadBalancer.TryGetNode());

            _reachabilityCheck = (_, __) => Task.FromResult(true);

            await Task.Delay(1000);

            var nodes = await Get20Nodes();

            nodes.ShouldContain(_node1);
            nodes.ShouldContain(_node2);
            nodes.ShouldContain(_node3);
        }
Ejemplo n.º 9
0
 public LoadBalancer(
     IDiscovery discovery,
     DeploymentIdentifier deploymentIdentifier,
     ReachabilityCheck reachabilityCheck,
     TrafficRoutingStrategy trafficRoutingStrategy,
     Func <Node, DeploymentIdentifier, ReachabilityCheck, Action, NodeMonitoringState> createNodeMonitoringState,
     IHealthMonitor healthMonitor,
     IDateTime dateTime,
     ILog log)
 {
     DeploymentIdentifier      = deploymentIdentifier;
     Discovery                 = discovery;
     ReachabilityCheck         = reachabilityCheck;
     TrafficRoutingStrategy    = trafficRoutingStrategy;
     CreateNodeMonitoringState = createNodeMonitoringState;
     DateTime       = dateTime;
     Log            = log;
     _healthMonitor = healthMonitor.SetHealthFunction(DeploymentIdentifier.ToString(), () => new ValueTask <HealthCheckResult>(_healthStatus));
 }
Ejemplo n.º 10
0
        public async Task GetNode_TwoNodesUnreachable_OneBecomesReachable_ReturnOnlyReachableNode()
        {
            Node nodeToBeUnreachable = null;

            _reachabilityCheck = async(n, c) =>
            {
                // ReSharper disable once AccessToModifiedClosure
                if (Equals(n, nodeToBeUnreachable))
                {
                    throw new Exception("This node is still unreachable");
                }
            };
            CreateLoadBalancer();

            var allNodes = new[] { _node1, _node2, _node3 };

            SetupSourceNodes(allNodes);

            nodeToBeUnreachable = await _loadBalancer.TryGetNode();

            var nodeToBeReachable = await GetDifferentNode(nodeToBeUnreachable);

            _loadBalancer.ReportUnreachable(nodeToBeReachable);
            _loadBalancer.ReportUnreachable(nodeToBeUnreachable);

            await Task.Delay(1000);

            var nodes = await Get20Nodes();

            foreach (var node in allNodes)
            {
                if (node.Equals(nodeToBeUnreachable))
                {
                    nodes.ShouldNotContain(node);
                }
                else
                {
                    nodes.ShouldContain(node);
                }
            }
        }
Ejemplo n.º 11
0
        public async Task GetNode_NodeUnreachableThenReturnsInBackground_NodeShouldBeReturned()
        {
            CreateLoadBalancer();
            SetupDefaultNodes();
            _reachabilityCheck = (_, __) => throw new EnvironmentException("node is unreachable");

            var selectedNode = await _loadBalancer.TryGetNode();

            _loadBalancer.ReportUnreachable(selectedNode);

            (await Get20Nodes()).ShouldNotContain(selectedNode);

            var waitForReachablitiy = new TaskCompletionSource <bool>();

            _reachabilityCheck = (_, __) =>
            {
                waitForReachablitiy.SetResult(true);
                return(Task.FromResult(true));
            };
            await waitForReachablitiy.Task;
            await Task.Delay(50);

            (await Get20Nodes()).ShouldContain(selectedNode);
        }
Ejemplo n.º 12
0
 public ILoadBalancer CreateLoadBalancer(DeploymentIdentifier deploymentIdentifier, ReachabilityCheck reachabilityCheck, TrafficRoutingStrategy trafficRoutingStrategy)
 {
     return(_createLoadBalancer(deploymentIdentifier, new LocalNodeSource(), reachabilityCheck, trafficRoutingStrategy));
 }