Esempio n. 1
0
        private void UpdateRuntimeBackends(DynamicConfigRoot config)
        {
            var desiredBackends = new HashSet <string>(StringComparer.Ordinal);

            foreach (var configBackendPair in config.Backends)
            {
                var configBackend = configBackendPair.Value;
                desiredBackends.Add(configBackendPair.Key);

                _backendManager.GetOrCreateItem(
                    itemId: configBackendPair.Key,
                    setupAction: backend =>
                {
                    UpdateRuntimeEndpoints(configBackend.Endpoints, backend.EndpointManager);

                    var newConfig = new BackendConfig(
                        new BackendConfig.BackendHealthCheckOptions(
                            enabled: configBackend.HealthCheckOptions?.Enabled ?? false,
                            interval: configBackend.HealthCheckOptions?.Interval ?? TimeSpan.FromSeconds(0),
                            timeout: configBackend.HealthCheckOptions?.Timeout ?? TimeSpan.FromSeconds(0),
                            port: configBackend.HealthCheckOptions?.Port ?? 0,
                            path: configBackend.HealthCheckOptions?.Path ?? string.Empty),
                        new BackendConfig.BackendLoadBalancingOptions(
                            mode: configBackend.LoadBalancing?.Mode ?? default));

                    var currentBackendConfig = backend.Config.Value;
                    if (currentBackendConfig == null ||
                        currentBackendConfig.HealthCheckOptions.Enabled != newConfig.HealthCheckOptions.Enabled ||
                        currentBackendConfig.HealthCheckOptions.Interval != newConfig.HealthCheckOptions.Interval ||
                        currentBackendConfig.HealthCheckOptions.Timeout != newConfig.HealthCheckOptions.Timeout ||
                        currentBackendConfig.HealthCheckOptions.Port != newConfig.HealthCheckOptions.Port ||
                        currentBackendConfig.HealthCheckOptions.Path != newConfig.HealthCheckOptions.Path)
                    {
                        if (currentBackendConfig == null)
                        {
                            _logger.LogDebug("Backend {backendId} has been added.", configBackendPair.Key);
                        }
                        else
                        {
                            _logger.LogDebug("Backend {backendId} has changed.", configBackendPair.Key);
                        }

                        // Config changed, so update runtime backend
                        backend.Config.Value = newConfig;
                    }
                });
            }

            foreach (var existingBackend in _backendManager.GetItems())
            {
                if (!desiredBackends.Contains(existingBackend.BackendId))
                {
                    // NOTE 1: This is safe to do within the `foreach` loop
                    // because `IBackendManager.GetItems` returns a copy of the list of backends.
                    //
                    // NOTE 2: Removing the backend from `IBackendManager` is safe and existing
                    // ASP .NET Core endpoints will continue to work with their existing behavior (until those endpoints are updated)
                    // and the Garbage Collector won't destroy this backend object while it's referenced elsewhere.
                    _logger.LogDebug("Backend {backendId} has been removed.", existingBackend.BackendId);
                    _backendManager.TryRemoveItem(existingBackend.BackendId);
                }
            }
        }