コード例 #1
0
        ///<inheritdoc />
        public async Task <NodeAndLoadBalancer> GetNode()
        {
            _lastUsageTime = DateTime.UtcNow;
            NodeAndLoadBalancer nodeAndLoadBalancer = null;
            string preferredEnvironment             = TracingContext.GetPreferredEnvironment();

            // 1. Use explicit host override if provided in request
            //    TBD: Theoretically if we only ever call a service through host overrides we might not have a health check for the service at all (though it is in use)
            var hostOverride = TracingContext.GetHostOverride(ServiceName);

            if (hostOverride != null)
            {
                return new NodeAndLoadBalancer {
                           Node                 = new Node(hostOverride.Host, hostOverride.Port),
                           LoadBalancer         = null,
                           PreferredEnvironment = preferredEnvironment ?? Environment.DeploymentEnvironment,
                }
            }
            ;

            // 2. Otherwise, use preferred environment if provided in request
            if (preferredEnvironment != null && (nodeAndLoadBalancer = await GetNodeAndLoadBalancer(preferredEnvironment, preferredEnvironment)) != null)
            {
                return(nodeAndLoadBalancer);
            }

            // 3. Otherwise, try use current environment
            if ((nodeAndLoadBalancer = await GetNodeAndLoadBalancer(Environment.DeploymentEnvironment, preferredEnvironment)) != null)
            {
                _healthStatus = new HealthMessage(Health.Healthy, message: null, suppressMessage: true); // No need for a health message since the load balancer we're returning already provides one
                return(nodeAndLoadBalancer);
            }

            // 4. We're in prod env and service is not deployed, no fallback possible
            if (Environment.DeploymentEnvironment == MASTER_ENVIRONMENT)
            {
                _healthStatus = new HealthMessage(Health.Unhealthy, "Service not deployed");
                throw ServiceNotDeployedException();
            }

            // 5. We're not in prod, but fallback to prod is disabled
            if (GetDiscoveryConfig().EnvironmentFallbackEnabled == false)
            {
                _healthStatus = new HealthMessage(Health.Unhealthy, "Service not deployed (and fallback to prod disabled)");
                throw ServiceNotDeployedException();
            }

            // 6. Otherwise, try fallback to prod
            if ((nodeAndLoadBalancer = await GetNodeAndLoadBalancer(MASTER_ENVIRONMENT, preferredEnvironment ?? Environment.DeploymentEnvironment)) != null)
            {
                _healthStatus = new HealthMessage(Health.Healthy, "Service not deployed, falling back to prod");
                return(nodeAndLoadBalancer);
            }

            _healthStatus = new HealthMessage(Health.Unhealthy, "Service not deployed, fallback to prod enabled but service not deployed in prod either");
            throw ServiceNotDeployedException();
        }