private static void AddLegacyClusterConfigurationSupport(IServiceCollection services, ClusterConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (services.TryGetClusterConfiguration() != null) { throw new InvalidOperationException("Cannot configure legacy ClusterConfiguration support twice"); } // these will eventually be removed once our code doesn't depend on the old ClientConfiguration services.AddSingleton(configuration); services.TryAddSingleton <LegacyConfigurationWrapper>(); services.TryAddSingleton(sp => sp.GetRequiredService <LegacyConfigurationWrapper>().ClusterConfig.Globals); services.TryAddTransient(sp => sp.GetRequiredService <LegacyConfigurationWrapper>().NodeConfig); services.TryAddSingleton <Factory <NodeConfiguration> >( sp => { var initializationParams = sp.GetRequiredService <LegacyConfigurationWrapper>(); return(() => initializationParams.NodeConfig); }); services.Configure <ClusterOptions>(options => { if (string.IsNullOrWhiteSpace(options.ClusterId) && !string.IsNullOrWhiteSpace(configuration.Globals.ClusterId)) { options.ClusterId = configuration.Globals.ClusterId; } if (options.ServiceId == Guid.Empty) { options.ServiceId = configuration.Globals.ServiceId; } }); services.Configure <MultiClusterOptions>(options => { var globals = configuration.Globals; if (globals.HasMultiClusterNetwork) { options.HasMultiClusterNetwork = true; options.BackgroundGossipInterval = globals.BackgroundGossipInterval; options.DefaultMultiCluster = globals.DefaultMultiCluster?.ToList(); options.GlobalSingleInstanceNumberRetries = globals.GlobalSingleInstanceNumberRetries; options.GlobalSingleInstanceRetryInterval = globals.GlobalSingleInstanceRetryInterval; options.MaxMultiClusterGateways = globals.MaxMultiClusterGateways; options.UseGlobalSingleInstanceByDefault = globals.UseGlobalSingleInstanceByDefault; foreach (GlobalConfiguration.GossipChannelConfiguration channelConfig in globals.GossipChannels) { options.GossipChannels.Add(GlobalConfiguration.Remap(channelConfig.ChannelType), channelConfig.ConnectionString); } } }); services.TryAddFromExisting <IMessagingConfiguration, GlobalConfiguration>(); services.AddOptions <SiloStatisticsOptions>() .Configure <NodeConfiguration>((options, nodeConfig) => LegacyConfigurationExtensions.CopyStatisticsOptions(nodeConfig, options)) .Configure <GlobalConfiguration>((options, config) => { options.DeploymentLoadPublisherRefreshTime = config.DeploymentLoadPublisherRefreshTime; }); services.AddOptions <LoadSheddingOptions>() .Configure <NodeConfiguration>((options, nodeConfig) => { options.LoadSheddingEnabled = nodeConfig.LoadSheddingEnabled; options.LoadSheddingLimit = nodeConfig.LoadSheddingLimit; }); // Translate legacy configuration to new Options services.AddOptions <SiloMessagingOptions>() .Configure <GlobalConfiguration>((options, config) => { LegacyConfigurationExtensions.CopyCommonMessagingOptions(config, options); options.SiloSenderQueues = config.SiloSenderQueues; options.GatewaySenderQueues = config.GatewaySenderQueues; options.MaxForwardCount = config.MaxForwardCount; options.ClientDropTimeout = config.ClientDropTimeout; options.ClientRegistrationRefresh = config.ClientRegistrationRefresh; options.MaxRequestProcessingTime = config.MaxRequestProcessingTime; options.AssumeHomogenousSilosForTesting = config.AssumeHomogenousSilosForTesting; }) .Configure <NodeConfiguration>((options, config) => { options.PropagateActivityId = config.PropagateActivityId; LimitValue requestLimit = config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS); options.MaxEnqueuedRequestsSoftLimit = requestLimit.SoftLimitThreshold; options.MaxEnqueuedRequestsHardLimit = requestLimit.HardLimitThreshold; LimitValue statelessWorkerRequestLimit = config.LimitManager.GetLimit(LimitNames.LIMIT_MAX_ENQUEUED_REQUESTS_STATELESS_WORKER); options.MaxEnqueuedRequestsSoftLimit_StatelessWorker = statelessWorkerRequestLimit.SoftLimitThreshold; options.MaxEnqueuedRequestsHardLimit_StatelessWorker = statelessWorkerRequestLimit.HardLimitThreshold; }); services.Configure <NetworkingOptions>(options => LegacyConfigurationExtensions.CopyNetworkingOptions(configuration.Globals, options)); services.AddOptions <EndpointOptions>() .Configure <IOptions <SiloOptions> >((options, siloOptions) => { var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); if (!string.IsNullOrEmpty(nodeConfig.HostNameOrIPAddress) || nodeConfig.Port != 0) { options.AdvertisedIPAddress = nodeConfig.Endpoint.Address; options.SiloPort = nodeConfig.Endpoint.Port; } }); services.Configure <SerializationProviderOptions>(options => { options.SerializationProviders = configuration.Globals.SerializationProviders; options.FallbackSerializationProvider = configuration.Globals.FallbackSerializationProvider; }); services.Configure <TelemetryOptions>(options => { LegacyConfigurationExtensions.CopyTelemetryOptions(configuration.Defaults.TelemetryConfiguration, services, options); }); services.AddOptions <GrainClassOptions>().Configure <IOptions <SiloOptions> >((options, siloOptions) => { var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes); }); services.AddOptions <SchedulingOptions>() .Configure <GlobalConfiguration>((options, config) => { options.AllowCallChainReentrancy = config.AllowCallChainReentrancy; options.PerformDeadlockDetection = config.PerformDeadlockDetection; }) .Configure <NodeConfiguration>((options, nodeConfig) => { options.MaxActiveThreads = nodeConfig.MaxActiveThreads; options.DelayWarningThreshold = nodeConfig.DelayWarningThreshold; options.ActivationSchedulingQuantum = nodeConfig.ActivationSchedulingQuantum; options.TurnWarningLengthThreshold = nodeConfig.TurnWarningLengthThreshold; options.EnableWorkerThreadInjection = nodeConfig.EnableWorkerThreadInjection; LimitValue itemLimit = nodeConfig.LimitManager.GetLimit(LimitNames.LIMIT_MAX_PENDING_ITEMS); options.MaxPendingWorkItemsSoftLimit = itemLimit.SoftLimitThreshold; options.MaxPendingWorkItemsHardLimit = itemLimit.HardLimitThreshold; }); services.AddOptions <GrainCollectionOptions>().Configure <GlobalConfiguration>((options, config) => { options.CollectionQuantum = config.CollectionQuantum; options.CollectionAge = config.Application.DefaultCollectionAgeLimit; foreach (GrainTypeConfiguration grainConfig in config.Application.ClassSpecific) { if (grainConfig.CollectionAgeLimit.HasValue) { options.ClassSpecificCollectionAge.Add(grainConfig.FullTypeName, grainConfig.CollectionAgeLimit.Value); } } ; }); LegacyProviderConfigurator <ISiloLifecycle> .ConfigureServices(configuration.Globals.ProviderConfigurations, services); if (!string.IsNullOrWhiteSpace(configuration.Globals.DefaultPlacementStrategy)) { services.AddSingleton(typeof(PlacementStrategy), MapDefaultPlacementStrategy(configuration.Globals.DefaultPlacementStrategy)); } services.AddOptions <ActivationCountBasedPlacementOptions>().Configure <GlobalConfiguration>((options, config) => { options.ChooseOutOf = config.ActivationCountBasedPlacementChooseOutOf; }); services.AddOptions <StaticClusterDeploymentOptions>().Configure <ClusterConfiguration>((options, config) => { options.SiloNames = config.Overrides.Keys.ToList(); }); // add grain service configs as keyed services foreach (IGrainServiceConfiguration grainServiceConfiguration in configuration.Globals.GrainServiceConfigurations.GrainServices.Values) { var type = Type.GetType(grainServiceConfiguration.ServiceType); services.AddSingletonKeyedService(type, (sp, k) => grainServiceConfiguration); } // populate grain service options foreach (IGrainServiceConfiguration grainServiceConfiguration in configuration.Globals.GrainServiceConfigurations.GrainServices.Values) { services.AddGrainService(Type.GetType(grainServiceConfiguration.ServiceType)); } services.AddOptions <ConsistentRingOptions>().Configure <GlobalConfiguration>((options, config) => { options.UseVirtualBucketsConsistentRing = config.UseVirtualBucketsConsistentRing; options.NumVirtualBucketsConsistentRing = config.NumVirtualBucketsConsistentRing; }); services.AddOptions <ClusterMembershipOptions>() .Configure <GlobalConfiguration>((options, config) => { options.NumMissedTableIAmAliveLimit = config.NumMissedTableIAmAliveLimit; options.LivenessEnabled = config.LivenessEnabled; options.ProbeTimeout = config.ProbeTimeout; options.TableRefreshTimeout = config.TableRefreshTimeout; options.DeathVoteExpirationTimeout = config.DeathVoteExpirationTimeout; options.IAmAliveTablePublishTimeout = config.IAmAliveTablePublishTimeout; options.MaxJoinAttemptTime = config.MaxJoinAttemptTime; options.ExpectedClusterSize = config.ExpectedClusterSize; options.ValidateInitialConnectivity = config.ValidateInitialConnectivity; options.NumMissedProbesLimit = config.NumMissedProbesLimit; options.UseLivenessGossip = config.UseLivenessGossip; options.NumProbedSilos = config.NumProbedSilos; options.NumVotesForDeathDeclaration = config.NumVotesForDeathDeclaration; }) .Configure <ClusterConfiguration>((options, config) => { options.IsRunningAsUnitTest = config.IsRunningAsUnitTest; }); services.AddOptions <GrainVersioningOptions>() .Configure <GlobalConfiguration>((options, config) => { options.DefaultCompatibilityStrategy = config.DefaultCompatibilityStrategy?.GetType().Name ?? GrainVersioningOptions.DEFAULT_COMPATABILITY_STRATEGY; options.DefaultVersionSelectorStrategy = config.DefaultVersionSelectorStrategy?.GetType().Name ?? GrainVersioningOptions.DEFAULT_VERSION_SELECTOR_STRATEGY; }); services.AddOptions <PerformanceTuningOptions>() .Configure <NodeConfiguration>((options, config) => { options.DefaultConnectionLimit = config.DefaultConnectionLimit; options.Expect100Continue = config.Expect100Continue; options.UseNagleAlgorithm = config.UseNagleAlgorithm; options.MinDotNetThreadPoolSize = config.MinDotNetThreadPoolSize; }); services.AddOptions <TypeManagementOptions>() .Configure <GlobalConfiguration>((options, config) => { options.TypeMapRefreshInterval = config.TypeMapRefreshInterval; }); services.AddOptions <GrainDirectoryOptions>() .Configure <GlobalConfiguration>((options, config) => { options.CachingStrategy = Remap(config.DirectoryCachingStrategy); options.CacheSize = config.CacheSize; options.InitialCacheTTL = config.InitialCacheTTL; options.MaximumCacheTTL = config.MaximumCacheTTL; options.CacheTTLExtensionFactor = config.CacheTTLExtensionFactor; options.LazyDeregistrationDelay = config.DirectoryLazyDeregistrationDelay; }); }
public static IServiceCollection AddLegacyClusterConfigurationSupport(this IServiceCollection services, ClusterConfiguration configuration) { if (configuration == null) { throw new ArgumentNullException(nameof(configuration)); } if (services.Any(service => service.ServiceType == typeof(ClusterConfiguration))) { throw new InvalidOperationException("Cannot configure legacy ClusterConfiguration support twice"); } // these will eventually be removed once our code doesn't depend on the old ClientConfiguration services.AddSingleton(configuration); services.TryAddSingleton <LegacyConfigurationWrapper>(); services.TryAddSingleton(sp => sp.GetRequiredService <LegacyConfigurationWrapper>().ClusterConfig.Globals); services.TryAddTransient(sp => sp.GetRequiredService <LegacyConfigurationWrapper>().NodeConfig); services.TryAddSingleton <Factory <NodeConfiguration> >( sp => { var initializationParams = sp.GetRequiredService <LegacyConfigurationWrapper>(); return(() => initializationParams.NodeConfig); }); services.Configure <SiloOptions>(options => { if (string.IsNullOrWhiteSpace(options.ClusterId) && !string.IsNullOrWhiteSpace(configuration.Globals.ClusterId)) { options.ClusterId = configuration.Globals.ClusterId; } if (options.ServiceId == Guid.Empty) { options.ServiceId = configuration.Globals.ServiceId; } }); services.Configure <MultiClusterOptions>(options => { var globals = configuration.Globals; if (globals.HasMultiClusterNetwork) { options.HasMultiClusterNetwork = true; options.BackgroundGossipInterval = globals.BackgroundGossipInterval; options.DefaultMultiCluster = globals.DefaultMultiCluster?.ToList(); options.GlobalSingleInstanceNumberRetries = globals.GlobalSingleInstanceNumberRetries; options.GlobalSingleInstanceRetryInterval = globals.GlobalSingleInstanceRetryInterval; options.MaxMultiClusterGateways = globals.MaxMultiClusterGateways; options.UseGlobalSingleInstanceByDefault = globals.UseGlobalSingleInstanceByDefault; } }); services.TryAddFromExisting <IMessagingConfiguration, GlobalConfiguration>(); services.AddOptions <StatisticsOptions>() .Configure <NodeConfiguration>((options, nodeConfig) => LegacyConfigurationExtensions.CopyStatisticsOptions(nodeConfig, options)); // Translate legacy configuration to new Options services.Configure <SiloMessagingOptions>(options => { LegacyConfigurationExtensions.CopyCommonMessagingOptions(configuration.Globals, options); options.SiloSenderQueues = configuration.Globals.SiloSenderQueues; options.GatewaySenderQueues = configuration.Globals.GatewaySenderQueues; options.MaxForwardCount = configuration.Globals.MaxForwardCount; options.ClientDropTimeout = configuration.Globals.ClientDropTimeout; }); services.Configure <NetworkingOptions>(options => LegacyConfigurationExtensions.CopyNetworkingOptions(configuration.Globals, options)); services.AddOptions <EndpointOptions>() .Configure <IOptions <SiloOptions> >((options, siloOptions) => { var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); if (options.IPAddress == null && string.IsNullOrWhiteSpace(options.HostNameOrIPAddress)) { options.IPAddress = nodeConfig.Endpoint.Address; options.Port = nodeConfig.Endpoint.Port; } if (options.ProxyPort == 0 && nodeConfig.ProxyGatewayEndpoint != null) { options.ProxyPort = nodeConfig.ProxyGatewayEndpoint.Port; } }); services.Configure <SerializationProviderOptions>(options => { options.SerializationProviders = configuration.Globals.SerializationProviders; options.FallbackSerializationProvider = configuration.Globals.FallbackSerializationProvider; }); services.Configure <TelemetryOptions>(options => { LegacyConfigurationExtensions.CopyTelemetryOptions(configuration.Defaults.TelemetryConfiguration, services, options); }); services.AddOptions <GrainClassOptions>().Configure <IOptions <SiloOptions> >((options, siloOptions) => { var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes); }); LegacyMembershipConfigurator.ConfigureServices(configuration.Globals, services); services.AddOptions <SchedulingOptions>().Configure <GlobalConfiguration>((options, config) => { options.AllowCallChainReentrancy = config.AllowCallChainReentrancy; options.PerformDeadlockDetection = config.PerformDeadlockDetection; }); services.TryAddSingleton <LegacyProviderConfigurator.ScheduleTask>(sp => { OrleansTaskScheduler scheduler = sp.GetRequiredService <OrleansTaskScheduler>(); SystemTarget fallbackSystemTarget = sp.GetRequiredService <FallbackSystemTarget>(); return((taskFunc) => scheduler.QueueTask(taskFunc, fallbackSystemTarget.SchedulingContext)); }); LegacyProviderConfigurator <ISiloLifecycle> .ConfigureServices(configuration.Globals.ProviderConfigurations, services, SiloDefaultProviderInitStage, SiloDefaultProviderStartStage); return(services); }