///<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(); }