private static void AdjustConfig(ClusterConfiguration config) { // register stream provider config.Globals.RegisterStreamProvider <EventHubStreamProvider>(StreamProviderName, BuildProviderSettings()); config.AddAzureTableStorageProvider(ImplicitSubscription_RecoverableStream_CollectorGrain.StorageProviderName); // Make sure a node config exist for each silo in the cluster. // This is required for the DynamicClusterConfigDeploymentBalancer to properly balance queues. // GetConfigurationForNode will materialize a node in the configuration for each silo, if one does not already exist. config.GetOrCreateNodeConfigurationForSilo("Primary"); config.GetOrCreateNodeConfigurationForSilo("Secondary_1"); }
public ISiloBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .ConfigureLogging(builder => ConfigureLogging(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }
/// <summary> /// Allows silo config to be programmatically set. /// </summary> /// <param name="config">Configuration data for this silo and cluster.</param> private void SetSiloConfig(ClusterConfiguration config) { Config = config; if (Verbose > 0) { Config.Defaults.DefaultTraceLevel = (Severity.Verbose - 1 + Verbose); } if (!String.IsNullOrEmpty(DeploymentId)) { Config.Globals.DeploymentId = DeploymentId; } if (string.IsNullOrWhiteSpace(Name)) { throw new ArgumentException("SiloName not defined - cannot initialize config"); } NodeConfig = Config.GetOrCreateNodeConfigurationForSilo(Name); Type = NodeConfig.IsPrimaryNode ? Silo.SiloType.Primary : Silo.SiloType.Secondary; if (TraceFilePath != null) { var traceFileName = NodeConfig.TraceFileName; if (traceFileName != null && !Path.IsPathRooted(traceFileName)) { NodeConfig.TraceFileName = TraceFilePath + "\\" + traceFileName; } } ConfigLoaded = true; InitializeLogger(NodeConfig); }
public static NodeConfiguration AddNodeConfiguration(ClusterConfiguration config, Silo.SiloType siloType, short instanceNumber, int baseSiloPort, int baseGatewayPort) { string siloName; switch (siloType) { case Silo.SiloType.Primary: siloName = Silo.PrimarySiloName; break; default: siloName = $"Secondary_{instanceNumber}"; break; } NodeConfiguration nodeConfig = config.GetOrCreateNodeConfigurationForSilo(siloName); nodeConfig.HostNameOrIPAddress = "loopback"; nodeConfig.Port = baseSiloPort + instanceNumber; var proxyAddress = nodeConfig.ProxyGatewayEndpoint?.Address ?? config.Defaults.ProxyGatewayEndpoint?.Address; if (proxyAddress != null) { nodeConfig.ProxyGatewayEndpoint = new IPEndPoint(proxyAddress, baseGatewayPort + instanceNumber); } config.Overrides[siloName] = nodeConfig; return(nodeConfig); }
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 <SiloInitializationParameters>(); services.TryAddFromExisting <ILocalSiloDetails, SiloInitializationParameters>(); services.TryAddSingleton(sp => sp.GetRequiredService <SiloInitializationParameters>().ClusterConfig); services.TryAddSingleton(sp => sp.GetRequiredService <SiloInitializationParameters>().ClusterConfig.Globals); services.TryAddTransient(sp => sp.GetRequiredService <SiloInitializationParameters>().NodeConfig); services.TryAddSingleton <Factory <NodeConfiguration> >( sp => { var initializationParams = sp.GetRequiredService <SiloInitializationParameters>(); return(() => initializationParams.NodeConfig); }); 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.Configure <SerializationProviderOptions>(options => { options.SerializationProviders = configuration.Globals.SerializationProviders; options.FallbackSerializationProvider = configuration.Globals.FallbackSerializationProvider; }); services.AddOptions <GrainClassOptions>().Configure <IOptions <SiloIdentityOptions> >((options, identityOptions) => { var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(identityOptions.Value.SiloName); options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes); }); LegacyMembershipConfigurator.ConfigureServices(configuration.Globals, services); return(services); }
public static void AdjustClusterConfiguration(ClusterConfiguration config) { var settings = new Dictionary <string, string>(); // get initial settings from configs ProviderConfig.WriteProperties(settings); EventHubConfig.WriteProperties(settings); // add queue balancer setting settings.Add(PersistentStreamProviderConfig.QUEUE_BALANCER_TYPE, StreamQueueBalancerType.DynamicClusterConfigDeploymentBalancer.ToString()); // register stream provider config.Globals.RegisterStreamProvider <EventHubStreamProvider>(StreamProviderName, settings); config.Globals.RegisterStorageProvider <MemoryStorage>("PubSubStore"); // Make sure a node config exist for each silo in the cluster. // This is required for the DynamicClusterConfigDeploymentBalancer to properly balance queues. config.GetOrCreateNodeConfigurationForSilo("Primary"); config.GetOrCreateNodeConfigurationForSilo("Secondary_1"); }
/// <summary> /// Allows silo config to be programmatically set. /// </summary> /// <param name="config">Configuration data for this silo and cluster.</param> private void SetSiloConfig(ClusterConfiguration config) { Config = config; if (!String.IsNullOrEmpty(DeploymentId)) { Config.Globals.DeploymentId = DeploymentId; } if (string.IsNullOrWhiteSpace(Name)) { throw new ArgumentException("SiloName not defined - cannot initialize config"); } NodeConfig = Config.GetOrCreateNodeConfigurationForSilo(Name); Type = NodeConfig.IsPrimaryNode ? Silo.SiloType.Primary : Silo.SiloType.Secondary; ConfigLoaded = true; }
public async Task SimpleUsageScenarioTest() { var endpoints = new EndpointsCollection { CreateEndpoint(OrleansCommunicationListener.SiloEndpointName, 9082), CreateEndpoint(OrleansCommunicationListener.GatewayEndpointName, 8888) }; activationContext.GetEndpoints().Returns(_ => endpoints); var siloHost = Substitute.For <ISiloHost>(); var listener = new OrleansCommunicationListener(this.serviceContext, clusterConfig) { SiloHost = siloHost }; siloHost.NodeConfig.Returns(_ => clusterConfig.GetOrCreateNodeConfigurationForSilo(listener.SiloName)); var result = await listener.OpenAsync(CancellationToken.None); var publishedEndpoints = JsonConvert.DeserializeObject <FabricSiloInfo>(result); var siloAddress = publishedEndpoints.SiloAddress; siloAddress.Generation.ShouldBeEquivalentTo(864); siloAddress.Endpoint.Port.ShouldBeEquivalentTo(9082); var gatewayAddress = publishedEndpoints.GatewayAddress; gatewayAddress.Generation.ShouldBeEquivalentTo(864); gatewayAddress.Endpoint.Port.ShouldBeEquivalentTo(8888); siloHost.ReceivedWithAnyArgs(1).Start(null, null); siloHost.DidNotReceive().Stop(); siloHost.ClearReceivedCalls(); await listener.CloseAsync(CancellationToken.None); siloHost.Received(1).Stop(); siloHost.DidNotReceiveWithAnyArgs().Start(null, null); }
/// <summary> /// Start a new silo in the target cluster /// </summary> /// <param name="host">The target cluster</param> /// <param name="type">The type of the silo to deploy</param> /// <param name="options">The options to use for the silo</param> /// <param name="instanceCount">The instance count of the silo</param> /// <param name="shared">The shared AppDomain to use</param> /// <returns>A handle to the deployed silo</returns> public static SiloHandle StartOrleansSilo(TestingSiloHost host, Silo.SiloType type, TestingSiloOptions options, int instanceCount, AppDomain shared = null) { if (host == null) { throw new ArgumentNullException("host"); } // Load initial config settings, then apply some overrides below. ClusterConfiguration config = new ClusterConfiguration(); try { if (options.SiloConfigFile == null) { config.StandardLoad(); } else { config.LoadFromFile(options.SiloConfigFile.FullName); } } catch (FileNotFoundException) { if (options.SiloConfigFile != null && !string.Equals(options.SiloConfigFile.Name, TestingSiloOptions.DEFAULT_SILO_CONFIG_FILE, StringComparison.InvariantCultureIgnoreCase)) { // if the user is not using the defaults, then throw because the file was legitimally not found throw; } config = ClusterConfiguration.LocalhostPrimarySilo(); config.AddMemoryStorageProvider("Default"); config.AddMemoryStorageProvider("MemoryStore"); } int basePort = options.BasePort < 0 ? BasePort : options.BasePort; if (config.Globals.SeedNodes.Count > 0 && options.BasePort < 0) { config.PrimaryNode = config.Globals.SeedNodes[0]; } else { config.PrimaryNode = new IPEndPoint(IPAddress.Loopback, basePort); } config.Globals.SeedNodes.Clear(); config.Globals.SeedNodes.Add(config.PrimaryNode); if (!String.IsNullOrEmpty(host.DeploymentId)) { config.Globals.DeploymentId = host.DeploymentId; } config.Defaults.PropagateActivityId = options.PropagateActivityId; if (options.LargeMessageWarningThreshold > 0) { config.Defaults.LargeMessageWarningThreshold = options.LargeMessageWarningThreshold; } config.Globals.LivenessType = options.LivenessType; config.Globals.ReminderServiceType = options.ReminderServiceType; if (!String.IsNullOrEmpty(options.DataConnectionString)) { config.Globals.DataConnectionString = options.DataConnectionString; } host.Globals = config.Globals; string siloName; switch (type) { case Silo.SiloType.Primary: siloName = "Primary"; break; default: siloName = "Secondary_" + instanceCount.ToString(CultureInfo.InvariantCulture); break; } NodeConfiguration nodeConfig = config.GetOrCreateNodeConfigurationForSilo(siloName); nodeConfig.HostNameOrIPAddress = "loopback"; nodeConfig.Port = basePort + instanceCount; nodeConfig.DefaultTraceLevel = config.Defaults.DefaultTraceLevel; nodeConfig.PropagateActivityId = config.Defaults.PropagateActivityId; nodeConfig.BulkMessageLimit = config.Defaults.BulkMessageLimit; int?gatewayport = null; if (nodeConfig.ProxyGatewayEndpoint != null && nodeConfig.ProxyGatewayEndpoint.Address != null) { gatewayport = (options.ProxyBasePort < 0 ? ProxyBasePort : options.ProxyBasePort) + instanceCount; nodeConfig.ProxyGatewayEndpoint = new IPEndPoint(nodeConfig.ProxyGatewayEndpoint.Address, gatewayport.Value); } config.Globals.ExpectedClusterSize = 2; config.Overrides[siloName] = nodeConfig; AdjustForTest(config, options); WriteLog("Starting a new silo in app domain {0} with config {1}", siloName, config.ToString(siloName)); return(AppDomainSiloHandle.Create(siloName, type, config, nodeConfig, host.additionalAssemblies)); }
public ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .ConfigureServices(this.ConfigureServices) .AddApplicationPartsFromAppDomain() .AddApplicationPartsFromBasePath() .ConfigureLogging(builder => TestingUtils.ConfigureDefaultLoggingBuilder(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }
public ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .UseDynamoDBMembership(options => { options.ConnectionString = ConnectionString; }) .ConfigureLogging(builder => TestingUtils.ConfigureDefaultLoggingBuilder(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }
public static SiloHandle StartOrleansSilo(TestingSiloHost host, Silo.SiloType type, TestingSiloOptions options, int instanceCount, AppDomain shared = null) { if (host == null) { throw new ArgumentNullException("host"); } // Load initial config settings, then apply some overrides below. ClusterConfiguration config = new ClusterConfiguration(); if (options.SiloConfigFile == null) { config.StandardLoad(); } else { config.LoadFromFile(options.SiloConfigFile.FullName); } int basePort = options.BasePort < 0 ? BasePort : options.BasePort; if (config.Globals.SeedNodes.Count > 0 && options.BasePort < 0) { config.PrimaryNode = config.Globals.SeedNodes[0]; } else { config.PrimaryNode = new IPEndPoint(IPAddress.Loopback, basePort); } config.Globals.SeedNodes.Clear(); config.Globals.SeedNodes.Add(config.PrimaryNode); if (!String.IsNullOrEmpty(host.DeploymentId)) { config.Globals.DeploymentId = host.DeploymentId; } config.Defaults.PropagateActivityId = options.PropagateActivityId; if (options.LargeMessageWarningThreshold > 0) { config.Defaults.LargeMessageWarningThreshold = options.LargeMessageWarningThreshold; } config.Globals.LivenessType = options.LivenessType; config.Globals.ReminderServiceType = options.ReminderServiceType; if (!String.IsNullOrEmpty(options.DataConnectionString)) { config.Globals.DataConnectionString = options.DataConnectionString; } host.Globals = config.Globals; string siloName; switch (type) { case Silo.SiloType.Primary: siloName = "Primary"; break; default: siloName = "Secondary_" + instanceCount.ToString(CultureInfo.InvariantCulture); break; } NodeConfiguration nodeConfig = config.GetOrCreateNodeConfigurationForSilo(siloName); nodeConfig.HostNameOrIPAddress = "loopback"; nodeConfig.Port = basePort + instanceCount; nodeConfig.DefaultTraceLevel = config.Defaults.DefaultTraceLevel; nodeConfig.PropagateActivityId = config.Defaults.PropagateActivityId; nodeConfig.BulkMessageLimit = config.Defaults.BulkMessageLimit; if (nodeConfig.ProxyGatewayEndpoint != null && nodeConfig.ProxyGatewayEndpoint.Address != null) { int proxyBasePort = options.ProxyBasePort < 0 ? ProxyBasePort : options.ProxyBasePort; nodeConfig.ProxyGatewayEndpoint = new IPEndPoint(nodeConfig.ProxyGatewayEndpoint.Address, proxyBasePort + instanceCount); } config.Globals.ExpectedClusterSize = 2; config.Overrides[siloName] = nodeConfig; AdjustForTest(config, options); WriteLog("Starting a new silo in app domain {0} with config {1}", siloName, config.ToString(siloName)); AppDomain appDomain; Silo silo = host.LoadSiloInNewAppDomain(siloName, type, config, out appDomain); silo.Start(); SiloHandle retValue = new SiloHandle { Name = siloName, Silo = silo, Options = options, Endpoint = silo.SiloAddress.Endpoint, AppDomain = appDomain, }; host.ImportGeneratedAssemblies(retValue); return(retValue); }
public ISiloBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .ConfigureLogging(builder => TestingUtils.ConfigureDefaultLoggingBuilder(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName)) .UseInClusterTransactionManager(new TransactionsConfiguration()) .UseInMemoryTransactionLog() .UseTransactionalState()); }
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 ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .UseConsulMembership(options => { options.Address = new Uri(ConsulTestUtils.CONSUL_ENDPOINT); }) .ConfigureLogging(builder => TestingUtils.ConfigureDefaultLoggingBuilder(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }
public ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .ConfigureLogging(builder => TestingUtils.ConfigureDefaultLoggingBuilder(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName)) .UseInClusterTransactionManager(new TransactionsConfiguration()) .UseAzureTransactionLog(new AzureTransactionLogConfiguration() { // TODO: Find better way for test isolation. Possibly different partition keys. TableName = $"TransactionLog{((uint)clusterConfiguration.Globals.DeploymentId.GetHashCode())%100000}", ConnectionString = TestDefaultConfiguration.DataConnectionString }) .UseTransactionalState()); }
public ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { var builder = new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .ConfigureLogging(loggingBuilder => TestingUtils.ConfigureDefaultLoggingBuilder(loggingBuilder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName)); // Setup storage feature infrastructure. // - Setup infrastructure. // - Set default feature implementation - optional // Setup infrastructure builder.UseExampleStorage(); // Default storage feature factory - optional builder.UseAsDefaultExampleStorage <TableExampleStorageFactory>(); // Service will need to add types they want to use to collection // - Call extension functions from each implementation assembly to register it's classes. // Blob - from blob extension assembly builder.UseBlobExampleStorage("Blob"); // Table - from table extension assembly builder.UseTableExampleStorage("Table"); // Blarg - from blarg extension assembly //builder.UseBlargExampleStorage("Blarg"); return(builder); }
internal Silo(string name, SiloType siloType, ClusterConfiguration config, ILocalDataStore keyStore) { SystemStatus.Current = SystemStatus.Creating; CurrentSilo = this; var startTime = DateTime.UtcNow; this.siloType = siloType; Name = name; siloTerminatedEvent = new ManualResetEvent(false); OrleansConfig = config; globalConfig = config.Globals; config.OnConfigChange("Defaults", () => nodeConfig = config.GetOrCreateNodeConfigurationForSilo(name)); if (!LogManager.IsInitialized) { LogManager.Initialize(nodeConfig); } config.OnConfigChange("Defaults/Tracing", () => LogManager.Initialize(nodeConfig, true), false); MultiClusterRegistrationStrategy.Initialize(config.Globals); ActivationData.Init(config, nodeConfig); StatisticsCollector.Initialize(nodeConfig); SerializationManager.Initialize(globalConfig.SerializationProviders, this.globalConfig.FallbackSerializationProvider); initTimeout = globalConfig.MaxJoinAttemptTime; if (Debugger.IsAttached) { initTimeout = StandardExtensions.Max(TimeSpan.FromMinutes(10), globalConfig.MaxJoinAttemptTime); stopTimeout = initTimeout; } IPEndPoint here = nodeConfig.Endpoint; int generation = nodeConfig.Generation; if (generation == 0) { generation = SiloAddress.AllocateNewGeneration(); nodeConfig.Generation = generation; } LogManager.MyIPEndPoint = here; logger = LogManager.GetLogger("Silo", LoggerType.Runtime); logger.Info(ErrorCode.SiloGcSetting, "Silo starting with GC settings: ServerGC={0} GCLatencyMode={1}", GCSettings.IsServerGC, Enum.GetName(typeof(GCLatencyMode), GCSettings.LatencyMode)); if (!GCSettings.IsServerGC || !GCSettings.LatencyMode.Equals(GCLatencyMode.Batch)) { logger.Warn(ErrorCode.SiloGcWarning, "Note: Silo not running with ServerGC turned on or with GCLatencyMode.Batch enabled - recommend checking app config : <configuration>-<runtime>-<gcServer enabled=\"true\"> and <configuration>-<runtime>-<gcConcurrent enabled=\"false\"/>"); logger.Warn(ErrorCode.SiloGcWarning, "Note: ServerGC only kicks in on multi-core systems (settings enabling ServerGC have no effect on single-core machines)."); } logger.Info(ErrorCode.SiloInitializing, "-------------- Initializing {0} silo on host {1} MachineName {2} at {3}, gen {4} --------------", siloType, nodeConfig.DNSHostName, Environment.MachineName, here, generation); logger.Info(ErrorCode.SiloInitConfig, "Starting silo {0} with the following configuration= " + Environment.NewLine + "{1}", name, config.ToString(name)); if (keyStore != null) { // Re-establish reference to shared local key store in this app domain LocalDataStoreInstance.LocalDataStore = keyStore; } // Configure DI using Startup type bool usingCustomServiceProvider; Services = StartupBuilder.ConfigureStartup(nodeConfig.StartupTypeName, out usingCustomServiceProvider); healthCheckParticipants = new List <IHealthCheckParticipant>(); allSiloProviders = new List <IProvider>(); BufferPool.InitGlobalBufferPool(globalConfig); PlacementStrategy.Initialize(globalConfig); UnobservedExceptionsHandlerClass.SetUnobservedExceptionHandler(UnobservedExceptionHandler); AppDomain.CurrentDomain.UnhandledException += (obj, ev) => DomainUnobservedExceptionHandler(obj, (Exception)ev.ExceptionObject); try { grainFactory = Services.GetRequiredService <GrainFactory>(); } catch (InvalidOperationException exc) { logger.Error(ErrorCode.SiloStartError, "Exception during Silo.Start, GrainFactory was not registered in Dependency Injection container", exc); throw; } typeManager = new GrainTypeManager( here.Address.Equals(IPAddress.Loopback), grainFactory, new SiloAssemblyLoader(OrleansConfig.Defaults.AdditionalAssemblyDirectories)); // Performance metrics siloStatistics = new SiloStatisticsManager(globalConfig, nodeConfig); config.OnConfigChange("Defaults/LoadShedding", () => siloStatistics.MetricsTable.NodeConfig = nodeConfig, false); // The scheduler scheduler = new OrleansTaskScheduler(globalConfig, nodeConfig); healthCheckParticipants.Add(scheduler); // Initialize the message center var mc = new MessageCenter(here, generation, globalConfig, siloStatistics.MetricsTable); if (nodeConfig.IsGatewayNode) { mc.InstallGateway(nodeConfig.ProxyGatewayEndpoint); } messageCenter = mc; SiloIdentity = SiloAddress.ToLongString(); // GrainRuntime can be created only here, after messageCenter was created. grainRuntime = new GrainRuntime( globalConfig.ServiceId, SiloIdentity, grainFactory, new TimerRegistry(), new ReminderRegistry(), new StreamProviderManager(), Services); // Now the router/directory service // This has to come after the message center //; note that it then gets injected back into the message center.; localGrainDirectory = new LocalGrainDirectory(this); RegistrarManager.InitializeGrainDirectoryManager(localGrainDirectory, globalConfig.GlobalSingleInstanceNumberRetries); // Now the activation directory. // This needs to know which router to use so that it can keep the global directory in synch with the local one. activationDirectory = new ActivationDirectory(); // Now the consistent ring provider RingProvider = GlobalConfig.UseVirtualBucketsConsistentRing ? (IConsistentRingProvider) new VirtualBucketsRingProvider(SiloAddress, GlobalConfig.NumVirtualBucketsConsistentRing) : new ConsistentRingProvider(SiloAddress); // to preserve backwards compatibility, only use the service provider to inject grain dependencies if the user supplied his own // service provider, meaning that he is explicitly opting into it. var grainCreator = new GrainCreator(grainRuntime, usingCustomServiceProvider ? Services : null); Action <Dispatcher> setDispatcher; catalog = new Catalog(Constants.CatalogId, SiloAddress, Name, LocalGrainDirectory, typeManager, scheduler, activationDirectory, config, grainCreator, out setDispatcher); var dispatcher = new Dispatcher(scheduler, messageCenter, catalog, config); setDispatcher(dispatcher); RuntimeClient.Current = new InsideRuntimeClient( dispatcher, catalog, LocalGrainDirectory, SiloAddress, config, RingProvider, typeManager, grainFactory); messageCenter.RerouteHandler = InsideRuntimeClient.Current.RerouteMessage; messageCenter.SniffIncomingMessage = InsideRuntimeClient.Current.SniffIncomingMessage; siloStatistics.MetricsTable.Scheduler = scheduler; siloStatistics.MetricsTable.ActivationDirectory = activationDirectory; siloStatistics.MetricsTable.ActivationCollector = catalog.ActivationCollector; siloStatistics.MetricsTable.MessageCenter = messageCenter; DeploymentLoadPublisher.CreateDeploymentLoadPublisher(this, globalConfig); PlacementDirectorsManager.CreatePlacementDirectorsManager(globalConfig); // Now the incoming message agents incomingSystemAgent = new IncomingMessageAgent(Message.Categories.System, messageCenter, activationDirectory, scheduler, dispatcher); incomingPingAgent = new IncomingMessageAgent(Message.Categories.Ping, messageCenter, activationDirectory, scheduler, dispatcher); incomingAgent = new IncomingMessageAgent(Message.Categories.Application, messageCenter, activationDirectory, scheduler, dispatcher); membershipFactory = new MembershipFactory(); multiClusterFactory = new MultiClusterOracleFactory(); reminderFactory = new LocalReminderServiceFactory(); SystemStatus.Current = SystemStatus.Created; StringValueStatistic.FindOrCreate(StatisticNames.SILO_START_TIME, () => LogFormatter.PrintDate(startTime)); // this will help troubleshoot production deployment when looking at MDS logs. logger.Info(ErrorCode.SiloInitializingFinished, "-------------- Started silo {0}, ConsistentHashCode {1:X} --------------", SiloAddress.ToLongString(), SiloAddress.GetConsistentHashCode()); }
public ISiloBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { ISiloBuilder builder = new SiloBuilder(); return(builder.ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .ConfigureLogging(loggingBuilder => TestingUtils.ConfigureDefaultLoggingBuilder(loggingBuilder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }
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.AddOptions <GrainClassOptions>().Configure <IOptions <SiloOptions> >((options, siloOptions) => { var nodeConfig = configuration.GetOrCreateNodeConfigurationForSilo(siloOptions.Value.SiloName); options.ExcludedGrainTypes.AddRange(nodeConfig.ExcludedGrainTypes); }); LegacyMembershipConfigurator.ConfigureServices(configuration.Globals, services); return(services); }
public ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .UseAzureTableMembership(options => { options.ConnectionString = TestDefaultConfiguration.DataConnectionString; options.MaxStorageBusyRetries = 3; }) .ConfigureLogging(builder => TestingUtils.ConfigureDefaultLoggingBuilder(builder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }
public ISiloHostBuilder CreateSiloBuilder(string siloName, ClusterConfiguration clusterConfiguration) { return(new SiloHostBuilder() .ConfigureSiloName(siloName) .UseConfiguration(clusterConfiguration) .UseGrainBasedMembership() .ConfigureLogging(loggingBuilder => TestingUtils.ConfigureDefaultLoggingBuilder(loggingBuilder, clusterConfiguration.GetOrCreateNodeConfigurationForSilo(siloName).TraceFileName))); }