Exemple #1
0
        public ProtocolServices(
            Grain gr,
            ILoggerFactory loggerFactory,
            IMultiClusterRegistrationStrategy strategy,
            SerializationManager serializationManager,
            IInternalGrainFactory grainFactory,
            IOptions <SiloOptions> siloOptions,
            IOptions <MultiClusterOptions> multiClusterOptions,
            IMultiClusterOracle multiClusterOracle)
        {
            this.grain                = gr;
            this.log                  = loggerFactory.CreateLogger <ProtocolServices>();
            this.grainFactory         = grainFactory;
            this.RegistrationStrategy = strategy;
            this.SerializationManager = serializationManager;
            this.multiClusterOracle   = multiClusterOracle;
            this.siloOptions          = siloOptions.Value;
            this.multiClusterOptions  = multiClusterOptions.Value;

            if (!this.multiClusterOptions.HasMultiClusterNetwork)
            {
                // we are creating a default multi-cluster configuration containing exactly one cluster, this one.
                this.pseudoMultiClusterConfiguration = PseudoMultiClusterConfigurations.FindOrCreate(
                    this.siloOptions.ClusterId,
                    CreatePseudoConfig);
            }
        }
Exemple #2
0
        public ProtocolServices(
            Grain gr,
            Factory <string, Logger> logFactory,
            IMultiClusterRegistrationStrategy strategy,
            SerializationManager serializationManager,
            IInternalGrainFactory grainFactory,
            GlobalConfiguration globalConfig,
            IMultiClusterOracle multiClusterOracle)
        {
            this.grain                = gr;
            this.log                  = logFactory("LogConsistencyProtocolServices");
            this.grainFactory         = grainFactory;
            this.RegistrationStrategy = strategy;
            this.SerializationManager = serializationManager;
            this.multiClusterOracle   = multiClusterOracle;
            this.globalConfig         = globalConfig;

            if (!globalConfig.HasMultiClusterNetwork)
            {
                // we are creating a default multi-cluster configuration containing exactly one cluster, this one.
                this.pseudoMultiClusterConfiguration = PseudoMultiClusterConfigurations.FindOrCreate(
                    this.globalConfig.ClusterId,
                    CreatePseudoConfig);
            }
        }
Exemple #3
0
 public ManagementGrain(
     GlobalConfiguration globalConfig,
     IMultiClusterOracle multiClusterOracle,
     IInternalGrainFactory internalGrainFactory,
     ISiloStatusOracle siloStatusOracle,
     MembershipTableFactory membershipTableFactory)
 {
     this.globalConfig           = globalConfig;
     this.multiClusterOracle     = multiClusterOracle;
     this.internalGrainFactory   = internalGrainFactory;
     this.siloStatusOracle       = siloStatusOracle;
     this.membershipTableFactory = membershipTableFactory;
 }
 public ClusterGrainDirectory(
     LocalGrainDirectory r,
     GrainId grainId,
     string clusterId,
     IInternalGrainFactory grainFactory,
     IMultiClusterOracle multiClusterOracle) : base(grainId, r.MyAddress)
 {
     this.router             = r;
     this.clusterId          = clusterId;
     this.grainFactory       = grainFactory;
     this.logger             = r.Logger;
     this.multiClusterOracle = multiClusterOracle;
 }
 public GlobalSingleInstanceActivationMaintainer(
     LocalGrainDirectory router,
     Logger logger,
     GlobalConfiguration config,
     IInternalGrainFactory grainFactory,
     IMultiClusterOracle multiClusterOracle)
 {
     this.router             = router;
     this.logger             = logger;
     this.grainFactory       = grainFactory;
     this.config             = config;
     this.multiClusterOracle = multiClusterOracle;
     this.period             = config.GlobalSingleInstanceRetryInterval;
     logger.Verbose("GSIP:M GlobalSingleInstanceActivationMaintainer Started, Period = {0}", period);
 }
Exemple #6
0
 public ClusterGrainDirectory(
     ILocalSiloDetails localSiloDetails,
     LocalGrainDirectory localGrainDirectory,
     GrainId grainId,
     string clusterId,
     IInternalGrainFactory grainFactory,
     IMultiClusterOracle multiClusterOracle,
     ILoggerFactory loggerFactory) : base(grainId, localSiloDetails.SiloAddress, loggerFactory)
 {
     this.localGrainDirectory = localGrainDirectory;
     this.clusterId           = clusterId;
     this.grainFactory        = grainFactory;
     this.logger             = loggerFactory.CreateLogger <ClusterGrainDirectory>();
     this.multiClusterOracle = multiClusterOracle;
 }
Exemple #7
0
 public ManagementGrain(
     IOptions <MultiClusterOptions> multiClusterOptions,
     IMultiClusterOracle multiClusterOracle,
     IInternalGrainFactory internalGrainFactory,
     ISiloStatusOracle siloStatusOracle,
     MembershipTableFactory membershipTableFactory,
     GrainTypeManager grainTypeManager,
     IVersionStore versionStore)
 {
     this.multiClusterOptions    = multiClusterOptions.Value;
     this.multiClusterOracle     = multiClusterOracle;
     this.internalGrainFactory   = internalGrainFactory;
     this.siloStatusOracle       = siloStatusOracle;
     this.membershipTableFactory = membershipTableFactory;
     this.grainTypeManager       = grainTypeManager;
     this.versionStore           = versionStore;
 }
Exemple #8
0
 public ManagementGrain(
     GlobalConfiguration globalConfig,
     IMultiClusterOracle multiClusterOracle,
     IInternalGrainFactory internalGrainFactory,
     ISiloStatusOracle siloStatusOracle,
     MembershipTableFactory membershipTableFactory,
     GrainTypeManager grainTypeManager,
     IVersionStore versionStore)
 {
     this.globalConfig           = globalConfig;
     this.multiClusterOracle     = multiClusterOracle;
     this.internalGrainFactory   = internalGrainFactory;
     this.siloStatusOracle       = siloStatusOracle;
     this.membershipTableFactory = membershipTableFactory;
     this.grainTypeManager       = grainTypeManager;
     this.versionStore           = versionStore;
 }
 public GlobalSingleInstanceRegistrar(
     LocalGrainDirectory localDirectory,
     Factory <string, Logger> loggerFactory,
     GlobalSingleInstanceActivationMaintainer gsiActivationMaintainer,
     GlobalConfiguration config,
     IInternalGrainFactory grainFactory,
     IMultiClusterOracle multiClusterOracle)
 {
     this.directoryPartition      = localDirectory.DirectoryPartition;
     this.logger                  = loggerFactory(nameof(GlobalSingleInstanceRegistrar));
     this.gsiActivationMaintainer = gsiActivationMaintainer;
     this.numRetries              = config.GlobalSingleInstanceNumberRetries;
     this.grainFactory            = grainFactory;
     this.multiClusterOracle      = multiClusterOracle;
     this.hasMultiClusterNetwork  = config.HasMultiClusterNetwork;
     this.clusterId               = config.ClusterId;
 }
Exemple #10
0
 public GlobalSingleInstanceRegistrar(
     LocalGrainDirectory localDirectory,
     ILogger <GlobalSingleInstanceRegistrar> logger,
     GlobalSingleInstanceActivationMaintainer gsiActivationMaintainer,
     IInternalGrainFactory grainFactory,
     IMultiClusterOracle multiClusterOracle,
     ILocalSiloDetails siloDetails,
     IOptions <MultiClusterOptions> multiClusterOptions)
 {
     this.directoryPartition      = localDirectory.DirectoryPartition;
     this.logger                  = logger;
     this.gsiActivationMaintainer = gsiActivationMaintainer;
     this.numRetries              = multiClusterOptions.Value.GlobalSingleInstanceNumberRetries;
     this.grainFactory            = grainFactory;
     this.multiClusterOracle      = multiClusterOracle;
     this.hasMultiClusterNetwork  = multiClusterOptions.Value.HasMultiClusterNetwork;
     this.clusterId               = siloDetails.ClusterId;
 }
Exemple #11
0
 public GlobalSingleInstanceActivationMaintainer(
     LocalGrainDirectory router,
     ILogger logger,
     IInternalGrainFactory grainFactory,
     IMultiClusterOracle multiClusterOracle,
     ExecutorService executorService,
     ILocalSiloDetails siloDetails,
     IOptions <MultiClusterOptions> multiClusterOptions,
     ILoggerFactory loggerFactory)
     : base(executorService, loggerFactory)
 {
     this.router              = router;
     this.logger              = logger;
     this.grainFactory        = grainFactory;
     this.multiClusterOracle  = multiClusterOracle;
     this.siloDetails         = siloDetails;
     this.multiClusterOptions = multiClusterOptions.Value;
     this.period              = multiClusterOptions.Value.GlobalSingleInstanceRetryInterval;
     logger.Debug("GSIP:M GlobalSingleInstanceActivationMaintainer Started, Period = {0}", period);
 }
Exemple #12
0
        internal Silo(SiloInitializationParameters initializationParams, IServiceProvider services)
        {
            string name = initializationParams.Name;
            ClusterConfiguration config = initializationParams.ClusterConfig;

            this.initializationParams = initializationParams;

            this.SystemStatus      = SystemStatus.Creating;
            AsynchAgent.IsStarting = true;

            var startTime = DateTime.UtcNow;

            services?.GetService <TelemetryManager>()?.AddFromConfiguration(services, LocalConfig.TelemetryConfiguration);
            StatisticsCollector.Initialize(LocalConfig);

            initTimeout = GlobalConfig.MaxJoinAttemptTime;
            if (Debugger.IsAttached)
            {
                initTimeout = StandardExtensions.Max(TimeSpan.FromMinutes(10), GlobalConfig.MaxJoinAttemptTime);
                stopTimeout = initTimeout;
            }

            var localEndpoint = this.initializationParams.SiloAddress.Endpoint;

            // Configure DI using Startup type
            if (services == null)
            {
                var serviceCollection = new ServiceCollection();
                serviceCollection.AddSingleton <Silo>(this);
                serviceCollection.AddSingleton(initializationParams);
                serviceCollection.AddLegacyClusterConfigurationSupport(config);
                serviceCollection.Configure <SiloIdentityOptions>(options => options.SiloName = name);
                var hostContext = new HostBuilderContext(new Dictionary <object, object>());
                DefaultSiloServices.AddDefaultServices(hostContext, serviceCollection);

                var applicationPartManager = hostContext.GetApplicationPartManager();
                applicationPartManager.AddApplicationPartsFromAppDomain();
                applicationPartManager.AddApplicationPartsFromBasePath();

                services = StartupBuilder.ConfigureStartup(this.LocalConfig.StartupTypeName, serviceCollection);
                services.GetService <TelemetryManager>()?.AddFromConfiguration(services, LocalConfig.TelemetryConfiguration);
            }

            services.GetService <SerializationManager>().RegisterSerializers(services.GetService <ApplicationPartManager>());

            this.Services = services;
            this.Services.InitializeSiloUnobservedExceptionsHandler();
            //set PropagateActivityId flag from node cofnig
            RequestContext.PropagateActivityId = this.initializationParams.NodeConfig.PropagateActivityId;
            this.loggerFactory = this.Services.GetRequiredService <ILoggerFactory>();
            logger             = this.loggerFactory.CreateLogger <Silo>();

            logger.Info(ErrorCode.SiloGcSetting, "Silo starting with GC settings: ServerGC={0} GCLatencyMode={1}", GCSettings.IsServerGC, Enum.GetName(typeof(GCLatencyMode), GCSettings.LatencyMode));
            if (!GCSettings.IsServerGC)
            {
                logger.Warn(ErrorCode.SiloGcWarning, "Note: Silo not running with ServerGC turned on - recommend checking app config : <configuration>-<runtime>-<gcServer enabled=\"true\">");
                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} --------------",
                        this.initializationParams.Type, LocalConfig.DNSHostName, Environment.MachineName, localEndpoint, this.initializationParams.SiloAddress.Generation);
            logger.Info(ErrorCode.SiloInitConfig, "Starting silo {0} with the following configuration= " + Environment.NewLine + "{1}",
                        name, config.ToString(name));

            var siloMessagingOptions = this.Services.GetRequiredService <IOptions <SiloMessagingOptions> >();

            BufferPool.InitGlobalBufferPool(siloMessagingOptions);

            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;
            }

            // Performance metrics
            siloStatistics = Services.GetRequiredService <SiloStatisticsManager>();

            // The scheduler
            scheduler = Services.GetRequiredService <OrleansTaskScheduler>();
            healthCheckParticipants.Add(scheduler);

            runtimeClient = Services.GetRequiredService <InsideRuntimeClient>();

            // Initialize the message center
            messageCenter = Services.GetRequiredService <MessageCenter>();
            var dispatcher = this.Services.GetRequiredService <Dispatcher>();

            messageCenter.RerouteHandler       = dispatcher.RerouteMessage;
            messageCenter.SniffIncomingMessage = runtimeClient.SniffIncomingMessage;

            // GrainRuntime can be created only here, after messageCenter was created.
            grainRuntime          = Services.GetRequiredService <IGrainRuntime>();
            StreamProviderManager = Services.GetRequiredService <IStreamProviderManager>();

            // 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 = Services.GetRequiredService <LocalGrainDirectory>();

            // Now the activation directory.
            activationDirectory = Services.GetRequiredService <ActivationDirectory>();

            // Now the consistent ring provider
            RingProvider = Services.GetRequiredService <IConsistentRingProvider>();

            catalog = Services.GetRequiredService <Catalog>();
            siloStatistics.MetricsTable.Scheduler           = scheduler;
            siloStatistics.MetricsTable.ActivationDirectory = activationDirectory;
            siloStatistics.MetricsTable.ActivationCollector = catalog.ActivationCollector;
            siloStatistics.MetricsTable.MessageCenter       = messageCenter;

            executorService = Services.GetRequiredService <ExecutorService>();

            // Now the incoming message agents
            var messageFactory = this.Services.GetRequiredService <MessageFactory>();

            incomingSystemAgent = new IncomingMessageAgent(Message.Categories.System, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory, executorService, this.loggerFactory);
            incomingPingAgent   = new IncomingMessageAgent(Message.Categories.Ping, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory, executorService, this.loggerFactory);
            incomingAgent       = new IncomingMessageAgent(Message.Categories.Application, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory, executorService, this.loggerFactory);

            membershipOracle = Services.GetRequiredService <IMembershipOracle>();

            if (!this.GlobalConfig.HasMultiClusterNetwork)
            {
                logger.Info("Skip multicluster oracle creation (no multicluster network configured)");
            }
            else
            {
                multiClusterOracle = Services.GetRequiredService <IMultiClusterOracle>();
            }

            this.SystemStatus      = SystemStatus.Created;
            AsynchAgent.IsStarting = false;

            StringValueStatistic.FindOrCreate(StatisticNames.SILO_START_TIME,
                                              () => LogFormatter.PrintDate(startTime)); // this will help troubleshoot production deployment when looking at MDS logs.

            var fullSiloLifecycle = this.Services.GetRequiredService <SiloLifecycle>();

            this.siloLifecycle = fullSiloLifecycle;
            IEnumerable <ILifecycleParticipant <ISiloLifecycle> > lifecyleParticipants = this.Services.GetServices <ILifecycleParticipant <ISiloLifecycle> >();

            foreach (ILifecycleParticipant <ISiloLifecycle> participant in lifecyleParticipants)
            {
                participant.Participate(fullSiloLifecycle);
            }
            this.Participate(fullSiloLifecycle);

            logger.Info(ErrorCode.SiloInitializingFinished, "-------------- Started silo {0}, ConsistentHashCode {1:X} --------------", SiloAddress.ToLongString(), SiloAddress.GetConsistentHashCode());
        }
Exemple #13
0
        public Silo(ILocalSiloDetails siloDetails, IServiceProvider services)
        {
            string name = siloDetails.Name;

            // Temporarily still require this. Hopefuly gone when 2.0 is released.
            this.siloDetails       = siloDetails;
            this.SystemStatus      = SystemStatus.Creating;
            AsynchAgent.IsStarting = true; // todo. use ISiloLifecycle instead?

            var startTime = DateTime.UtcNow;

            IOptions <ClusterMembershipOptions> clusterMembershipOptions = services.GetRequiredService <IOptions <ClusterMembershipOptions> >();

            initTimeout = clusterMembershipOptions.Value.MaxJoinAttemptTime;
            if (Debugger.IsAttached)
            {
                initTimeout = StandardExtensions.Max(TimeSpan.FromMinutes(10), clusterMembershipOptions.Value.MaxJoinAttemptTime);
                stopTimeout = initTimeout;
            }

            var localEndpoint = this.siloDetails.SiloAddress.Endpoint;

            services.GetService <SerializationManager>().RegisterSerializers(services.GetService <IApplicationPartManager>());

            this.Services = services;
            this.Services.InitializeSiloUnobservedExceptionsHandler();
            //set PropagateActivityId flag from node config
            IOptions <SiloMessagingOptions> messagingOptions = services.GetRequiredService <IOptions <SiloMessagingOptions> >();

            RequestContext.PropagateActivityId = messagingOptions.Value.PropagateActivityId;
            this.loggerFactory = this.Services.GetRequiredService <ILoggerFactory>();
            logger             = this.loggerFactory.CreateLogger <Silo>();

            logger.Info(ErrorCode.SiloGcSetting, "Silo starting with GC settings: ServerGC={0} GCLatencyMode={1}", GCSettings.IsServerGC, Enum.GetName(typeof(GCLatencyMode), GCSettings.LatencyMode));
            if (!GCSettings.IsServerGC)
            {
                logger.Warn(ErrorCode.SiloGcWarning, "Note: Silo not running with ServerGC turned on - recommend checking app config : <configuration>-<runtime>-<gcServer enabled=\"true\">");
                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 silo on host {0} MachineName {1} at {2}, gen {3} --------------",
                        this.siloDetails.DnsHostName, Environment.MachineName, localEndpoint, this.siloDetails.SiloAddress.Generation);
            logger.Info(ErrorCode.SiloInitConfig, "Starting silo {0}", name);

            var siloMessagingOptions = this.Services.GetRequiredService <IOptions <SiloMessagingOptions> >();

            BufferPool.InitGlobalBufferPool(siloMessagingOptions.Value);

            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;
            }

            // Performance metrics
            siloStatistics = Services.GetRequiredService <SiloStatisticsManager>();

            // The scheduler
            scheduler = Services.GetRequiredService <OrleansTaskScheduler>();
            healthCheckParticipants.Add(scheduler);

            runtimeClient = Services.GetRequiredService <InsideRuntimeClient>();

            // Initialize the message center
            messageCenter = Services.GetRequiredService <MessageCenter>();
            var dispatcher = this.Services.GetRequiredService <Dispatcher>();

            messageCenter.RerouteHandler       = dispatcher.RerouteMessage;
            messageCenter.SniffIncomingMessage = runtimeClient.SniffIncomingMessage;

            // 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 = Services.GetRequiredService <LocalGrainDirectory>();

            // Now the activation directory.
            activationDirectory = Services.GetRequiredService <ActivationDirectory>();

            // Now the consistent ring provider
            RingProvider = Services.GetRequiredService <IConsistentRingProvider>();

            catalog = Services.GetRequiredService <Catalog>();

            executorService = Services.GetRequiredService <ExecutorService>();

            // Now the incoming message agents
            var messageFactory = this.Services.GetRequiredService <MessageFactory>();

            incomingSystemAgent = new IncomingMessageAgent(Message.Categories.System, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory, executorService, this.loggerFactory);
            incomingPingAgent   = new IncomingMessageAgent(Message.Categories.Ping, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory, executorService, this.loggerFactory);
            incomingAgent       = new IncomingMessageAgent(Message.Categories.Application, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory, executorService, this.loggerFactory);

            membershipOracle    = Services.GetRequiredService <IMembershipOracle>();
            this.clusterOptions = Services.GetRequiredService <IOptions <ClusterOptions> >().Value;
            var multiClusterOptions = Services.GetRequiredService <IOptions <MultiClusterOptions> >().Value;

            if (!multiClusterOptions.HasMultiClusterNetwork)
            {
                logger.Info("Skip multicluster oracle creation (no multicluster network configured)");
            }
            else
            {
                multiClusterOracle = Services.GetRequiredService <IMultiClusterOracle>();
            }

            this.SystemStatus      = SystemStatus.Created;
            AsynchAgent.IsStarting = false;

            StringValueStatistic.FindOrCreate(StatisticNames.SILO_START_TIME,
                                              () => LogFormatter.PrintDate(startTime)); // this will help troubleshoot production deployment when looking at MDS logs.

            this.siloLifecycle = this.Services.GetRequiredService <ISiloLifecycleSubject>();
            // register all lifecycle participants
            IEnumerable <ILifecycleParticipant <ISiloLifecycle> > lifecycleParticipants = this.Services.GetServices <ILifecycleParticipant <ISiloLifecycle> >();

            foreach (ILifecycleParticipant <ISiloLifecycle> participant in lifecycleParticipants)
            {
                participant?.Participate(this.siloLifecycle);
            }
            // register all named lifecycle participants
            IKeyedServiceCollection <string, ILifecycleParticipant <ISiloLifecycle> > namedLifecycleParticipantCollection = this.Services.GetService <IKeyedServiceCollection <string, ILifecycleParticipant <ISiloLifecycle> > >();

            foreach (ILifecycleParticipant <ISiloLifecycle> participant in namedLifecycleParticipantCollection
                     ?.GetServices(this.Services)
                     ?.Select(s => s.GetService(this.Services)))
            {
                participant?.Participate(this.siloLifecycle);
            }

            // add self to lifecycle
            this.Participate(this.siloLifecycle);

            logger.Info(ErrorCode.SiloInitializingFinished, "-------------- Started silo {0}, ConsistentHashCode {1:X} --------------", SiloAddress.ToLongString(), SiloAddress.GetConsistentHashCode());
        }
Exemple #14
0
        private void DoStart()
        {
            lock (lockable)
            {
                if (!SystemStatus.Current.Equals(SystemStatus.Created))
                    throw new InvalidOperationException(String.Format("Calling Silo.Start() on a silo which is not in the Created state. This silo is in the {0} state.", SystemStatus.Current));
                
                SystemStatus.Current = SystemStatus.Starting;
            }

            logger.Info(ErrorCode.SiloStarting, "Silo Start()");

            // Hook up to receive notification of process exit / Ctrl-C events
            AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            Console.CancelKeyPress += HandleProcessExit;

            ConfigureThreadPoolAndServicePointSettings();

            // This has to start first so that the directory system target factory gets loaded before we start the router.
            grainTypeManager.Start();
            runtimeClient.Start();

            // The order of these 4 is pretty much arbitrary.
            scheduler.Start();
            messageCenter.Start();
            incomingPingAgent.Start();
            incomingSystemAgent.Start();
            incomingAgent.Start();

            LocalGrainDirectory.Start();

            // Set up an execution context for this thread so that the target creation steps can use asynch values.
            RuntimeContext.InitializeMainThread();
            
            // Initialize the implicit stream subscribers table.
            var implicitStreamSubscriberTable = Services.GetRequiredService<ImplicitStreamSubscriberTable>();
            implicitStreamSubscriberTable.InitImplicitStreamSubscribers(this.grainTypeManager.GrainClassTypeData.Select(t => t.Value.Type).ToArray());

            var siloProviderRuntime = Services.GetRequiredService<SiloProviderRuntime>();
            runtimeClient.CurrentStreamProviderRuntime = siloProviderRuntime;
            statisticsProviderManager = new StatisticsProviderManager("Statistics", siloProviderRuntime);
            string statsProviderName =  statisticsProviderManager.LoadProvider(GlobalConfig.ProviderConfigurations)
                .WaitForResultWithThrow(initTimeout);
            if (statsProviderName != null)
                LocalConfig.StatisticsProviderName = statsProviderName;
            allSiloProviders.AddRange(statisticsProviderManager.GetProviders());

            // can call SetSiloMetricsTableDataManager only after MessageCenter is created (dependency on this.SiloAddress).
            siloStatistics.SetSiloStatsTableDataManager(this, LocalConfig).WaitWithThrow(initTimeout);
            siloStatistics.SetSiloMetricsTableDataManager(this, LocalConfig).WaitWithThrow(initTimeout);

            IMembershipTable membershipTable = Services.GetRequiredService<IMembershipTable>();
            
            multiClusterOracle =
                Services.GetRequiredService<MultiClusterOracleFactory>().CreateGossipOracle(this).WaitForResultWithThrow(initTimeout);

            // This has to follow the above steps that start the runtime components
            CreateSystemTargets();

            InjectDependencies();

            // Validate the configuration.
            GlobalConfig.Application.ValidateConfiguration(logger);

            // ensure this runs in the grain context, wait for it to complete
            scheduler.QueueTask(CreateSystemGrains, catalog.SchedulingContext)
                .WaitWithThrow(initTimeout);
            if (logger.IsVerbose) {  logger.Verbose("System grains created successfully."); }

            // Initialize storage providers once we have a basic silo runtime environment operating
            storageProviderManager = new StorageProviderManager(grainFactory, Services, siloProviderRuntime);
            scheduler.QueueTask(
                () => storageProviderManager.LoadStorageProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
                    .WaitWithThrow(initTimeout);
            catalog.SetStorageManager(storageProviderManager);
            allSiloProviders.AddRange(storageProviderManager.GetProviders());
            if (logger.IsVerbose) { logger.Verbose("Storage provider manager created successfully."); }

            // Load and init stream providers before silo becomes active
            var siloStreamProviderManager = (StreamProviderManager)grainRuntime.StreamProviderManager;
            scheduler.QueueTask(
                () => siloStreamProviderManager.LoadStreamProviders(GlobalConfig.ProviderConfigurations, siloProviderRuntime),
                    providerManagerSystemTarget.SchedulingContext)
                        .WaitWithThrow(initTimeout);
            runtimeClient.CurrentStreamProviderManager = siloStreamProviderManager;
            allSiloProviders.AddRange(siloStreamProviderManager.GetProviders());
            if (logger.IsVerbose) { logger.Verbose("Stream provider manager created successfully."); }

            ISchedulingContext statusOracleContext = ((SystemTarget)LocalSiloStatusOracle).SchedulingContext;

            bool waitForPrimaryToStart = GlobalConfig.PrimaryNodeIsRequired && Type != SiloType.Primary;
            if (waitForPrimaryToStart) // only in MembershipTableGrain case.
            {
                scheduler.QueueTask(() => membershipFactory.WaitForTableToInit(membershipTable), statusOracleContext)
                        .WaitWithThrow(initTimeout);
            }
            scheduler.QueueTask(() => membershipTable.InitializeMembershipTable(GlobalConfig, true, LogManager.GetLogger(membershipTable.GetType().Name)), statusOracleContext)
                .WaitWithThrow(initTimeout);
          
            scheduler.QueueTask(() => LocalSiloStatusOracle.Start(), statusOracleContext)
                .WaitWithThrow(initTimeout);
            if (logger.IsVerbose) { logger.Verbose("Local silo status oracle created successfully."); }
            scheduler.QueueTask(LocalSiloStatusOracle.BecomeActive, statusOracleContext)
                .WaitWithThrow(initTimeout);
            if (logger.IsVerbose) { logger.Verbose("Local silo status oracle became active successfully."); }

            //if running in multi cluster scenario, start the MultiClusterNetwork Oracle
            if (GlobalConfig.HasMultiClusterNetwork) 
            {
                logger.Info("Creating multicluster oracle with my ServiceId={0} and ClusterId={1}.",
                    GlobalConfig.ServiceId, GlobalConfig.ClusterId);

                ISchedulingContext clusterStatusContext = ((SystemTarget) multiClusterOracle).SchedulingContext;
                scheduler.QueueTask(() => multiClusterOracle.Start(LocalSiloStatusOracle), clusterStatusContext)
                                    .WaitWithThrow(initTimeout);
                if (logger.IsVerbose) { logger.Verbose("multicluster oracle created successfully."); }
            }

            try
            {
                this.siloStatistics.Start(this.LocalConfig);
                if (this.logger.IsVerbose) { this.logger.Verbose("Silo statistics manager started successfully."); }

                // Finally, initialize the deployment load collector, for grains with load-based placement
                var deploymentLoadPublisher = Services.GetRequiredService<DeploymentLoadPublisher>();
                this.scheduler.QueueTask(deploymentLoadPublisher.Start, deploymentLoadPublisher.SchedulingContext)
                    .WaitWithThrow(this.initTimeout);
                if (this.logger.IsVerbose) { this.logger.Verbose("Silo deployment load publisher started successfully."); }

                // Start background timer tick to watch for platform execution stalls, such as when GC kicks in
                this.platformWatchdog = new Watchdog(this.LocalConfig.StatisticsLogWriteInterval, this.healthCheckParticipants);
                this.platformWatchdog.Start();
                if (this.logger.IsVerbose) { this.logger.Verbose("Silo platform watchdog started successfully."); }

                if (this.reminderService != null)
                {
                    // so, we have the view of the membership in the consistentRingProvider. We can start the reminder service
                    this.scheduler.QueueTask(this.reminderService.Start, ((SystemTarget)this.reminderService).SchedulingContext)
                        .WaitWithThrow(this.initTimeout);
                    if (this.logger.IsVerbose)
                    {
                        this.logger.Verbose("Reminder service started successfully.");
                    }
                }

                this.bootstrapProviderManager = new BootstrapProviderManager();
                this.scheduler.QueueTask(
                    () => this.bootstrapProviderManager.LoadAppBootstrapProviders(siloProviderRuntime, this.GlobalConfig.ProviderConfigurations),
                    this.providerManagerSystemTarget.SchedulingContext)
                        .WaitWithThrow(this.initTimeout);
                this.BootstrapProviders = this.bootstrapProviderManager.GetProviders(); // Data hook for testing & diagnotics
                this.allSiloProviders.AddRange(this.BootstrapProviders);

                if (this.logger.IsVerbose) { this.logger.Verbose("App bootstrap calls done successfully."); }

                // Start stream providers after silo is active (so the pulling agents don't start sending messages before silo is active).
                // also after bootstrap provider started so bootstrap provider can initialize everything stream before events from this silo arrive.
                this.scheduler.QueueTask(siloStreamProviderManager.StartStreamProviders, this.providerManagerSystemTarget.SchedulingContext)
                    .WaitWithThrow(this.initTimeout);
                if (this.logger.IsVerbose) { this.logger.Verbose("Stream providers started successfully."); }

                // Now that we're active, we can start the gateway
                var mc = this.messageCenter as MessageCenter;
                mc?.StartGateway(this.Services.GetRequiredService<ClientObserverRegistrar>());
                if (this.logger.IsVerbose) { this.logger.Verbose("Message gateway service started successfully."); }

                SystemStatus.Current = SystemStatus.Running;
            }
            catch (Exception exc)
            {
                this.SafeExecute(() => this.logger.Error(ErrorCode.Runtime_Error_100330, String.Format("Error starting silo {0}. Going to FastKill().", this.SiloAddress), exc));
                this.FastKill(); // if failed after Membership became active, mark itself as dead in Membership abale.
                throw;
            }
            if (logger.IsVerbose) { logger.Verbose("Silo.Start complete: System status = {0}", SystemStatus.Current); }
        }
Exemple #15
0
        internal Silo(SiloInitializationParameters initializationParams, IServiceProvider services)
        {
            string name = initializationParams.Name;
            ClusterConfiguration config = initializationParams.ClusterConfig;

            this.initializationParams = initializationParams;

            this.SystemStatus      = SystemStatus.Creating;
            AsynchAgent.IsStarting = true;

            var startTime = DateTime.UtcNow;

            if (!LogManager.IsInitialized)
            {
                LogManager.Initialize(LocalConfig);
            }
            services?.GetService <TelemetryManager>()?.AddFromConfiguration(services, LocalConfig.TelemetryConfiguration);

            config.OnConfigChange("Defaults/Tracing", () => LogManager.Initialize(LocalConfig, true), false);
            StatisticsCollector.Initialize(LocalConfig);

            initTimeout = GlobalConfig.MaxJoinAttemptTime;
            if (Debugger.IsAttached)
            {
                initTimeout = StandardExtensions.Max(TimeSpan.FromMinutes(10), GlobalConfig.MaxJoinAttemptTime);
                stopTimeout = initTimeout;
            }

            var localEndpoint = this.initializationParams.SiloAddress.Endpoint;

            LogManager.MyIPEndPoint = localEndpoint;
            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)
            {
                logger.Warn(ErrorCode.SiloGcWarning, "Note: Silo not running with ServerGC turned on - recommend checking app config : <configuration>-<runtime>-<gcServer enabled=\"true\">");
                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} --------------",
                        this.initializationParams.Type, LocalConfig.DNSHostName, Environment.MachineName, localEndpoint, this.initializationParams.SiloAddress.Generation);
            logger.Info(ErrorCode.SiloInitConfig, "Starting silo {0} with the following configuration= " + Environment.NewLine + "{1}",
                        name, config.ToString(name));

            // Configure DI using Startup type
            if (services == null)
            {
                var serviceCollection = new ServiceCollection();
                serviceCollection.AddSingleton <Silo>(this);
                serviceCollection.AddSingleton(initializationParams);
                DefaultSiloServices.AddDefaultServices(serviceCollection);
                services = StartupBuilder.ConfigureStartup(this.LocalConfig.StartupTypeName, serviceCollection);
                services.GetService <TelemetryManager>()?.AddFromConfiguration(services, LocalConfig.TelemetryConfiguration);
            }

            this.Services = services;

            this.assemblyProcessor = this.Services.GetRequiredService <AssemblyProcessor>();
            this.assemblyProcessor.Initialize();

            BufferPool.InitGlobalBufferPool(GlobalConfig);

            if (!UnobservedExceptionsHandlerClass.TrySetUnobservedExceptionHandler(UnobservedExceptionHandler))
            {
                logger.Warn(ErrorCode.Runtime_Error_100153, "Unable to set unobserved exception handler because it was already set.");
            }

            AppDomain.CurrentDomain.UnhandledException += this.DomainUnobservedExceptionHandler;

            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;
            }

            grainTypeManager = Services.GetRequiredService <GrainTypeManager>();

            // Performance metrics
            siloStatistics = Services.GetRequiredService <SiloStatisticsManager>();

            // The scheduler
            scheduler = Services.GetRequiredService <OrleansTaskScheduler>();
            healthCheckParticipants.Add(scheduler);

            runtimeClient = Services.GetRequiredService <InsideRuntimeClient>();

            // Initialize the message center
            messageCenter = Services.GetRequiredService <MessageCenter>();
            var dispatcher = this.Services.GetRequiredService <Dispatcher>();

            messageCenter.RerouteHandler       = dispatcher.RerouteMessage;
            messageCenter.SniffIncomingMessage = runtimeClient.SniffIncomingMessage;

            // GrainRuntime can be created only here, after messageCenter was created.
            grainRuntime = Services.GetRequiredService <IGrainRuntime>();

            // 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 = Services.GetRequiredService <LocalGrainDirectory>();

            // Now the activation directory.
            activationDirectory = Services.GetRequiredService <ActivationDirectory>();

            // Now the consistent ring provider
            RingProvider = Services.GetRequiredService <IConsistentRingProvider>();

            catalog = Services.GetRequiredService <Catalog>();
            siloStatistics.MetricsTable.Scheduler           = scheduler;
            siloStatistics.MetricsTable.ActivationDirectory = activationDirectory;
            siloStatistics.MetricsTable.ActivationCollector = catalog.ActivationCollector;
            siloStatistics.MetricsTable.MessageCenter       = messageCenter;

            // Now the incoming message agents
            var messageFactory = this.Services.GetRequiredService <MessageFactory>();

            incomingSystemAgent = new IncomingMessageAgent(Message.Categories.System, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory);
            incomingPingAgent   = new IncomingMessageAgent(Message.Categories.Ping, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory);
            incomingAgent       = new IncomingMessageAgent(Message.Categories.Application, messageCenter, activationDirectory, scheduler, catalog.Dispatcher, messageFactory);

            membershipOracle = Services.GetRequiredService <IMembershipOracle>();

            if (!this.GlobalConfig.HasMultiClusterNetwork)
            {
                logger.Info("Skip multicluster oracle creation (no multicluster network configured)");
            }
            else
            {
                multiClusterOracle = Services.GetRequiredService <IMultiClusterOracle>();
            }

            this.SystemStatus      = SystemStatus.Created;
            AsynchAgent.IsStarting = false;

            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());
        }
Exemple #16
0
        private void DoStart()
        {
            lock (lockable)
            {
                if (!SystemStatus.Current.Equals(SystemStatus.Created))
                {
                    throw new InvalidOperationException(String.Format("Calling Silo.Start() on a silo which is not in the Created state. This silo is in the {0} state.", SystemStatus.Current));
                }

                SystemStatus.Current = SystemStatus.Starting;
            }

            logger.Info(ErrorCode.SiloStarting, "Silo Start()");

            // Hook up to receive notification of process exit / Ctrl-C events
            AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            Console.CancelKeyPress += HandleProcessExit;

            ConfigureThreadPoolAndServicePointSettings();

            // This has to start first so that the directory system target factory gets loaded before we start the router.
            typeManager.Start();
            InsideRuntimeClient.Current.Start();

            // The order of these 4 is pretty much arbitrary.
            scheduler.Start();
            messageCenter.Start();
            incomingPingAgent.Start();
            incomingSystemAgent.Start();
            incomingAgent.Start();

            LocalGrainDirectory.Start();

            // Set up an execution context for this thread so that the target creation steps can use asynch values.
            RuntimeContext.InitializeMainThread();

            SiloProviderRuntime.Initialize(GlobalConfig, SiloIdentity, grainFactory, Services);
            InsideRuntimeClient.Current.CurrentStreamProviderRuntime = SiloProviderRuntime.Instance;
            statisticsProviderManager = new StatisticsProviderManager("Statistics", SiloProviderRuntime.Instance);
            string statsProviderName = statisticsProviderManager.LoadProvider(GlobalConfig.ProviderConfigurations)
                                       .WaitForResultWithThrow(initTimeout);

            if (statsProviderName != null)
            {
                LocalConfig.StatisticsProviderName = statsProviderName;
            }
            allSiloProviders.AddRange(statisticsProviderManager.GetProviders());

            // can call SetSiloMetricsTableDataManager only after MessageCenter is created (dependency on this.SiloAddress).
            siloStatistics.SetSiloStatsTableDataManager(this, nodeConfig).WaitWithThrow(initTimeout);
            siloStatistics.SetSiloMetricsTableDataManager(this, nodeConfig).WaitWithThrow(initTimeout);

            IMembershipTable membershipTable = membershipFactory.GetMembershipTable(GlobalConfig.LivenessType, GlobalConfig.MembershipTableAssembly);

            membershipOracle   = membershipFactory.CreateMembershipOracle(this, membershipTable);
            multiClusterOracle = multiClusterFactory.CreateGossipOracle(this).WaitForResultWithThrow(initTimeout);

            // This has to follow the above steps that start the runtime components
            CreateSystemTargets();

            InjectDependencies();

            // Validate the configuration.
            GlobalConfig.Application.ValidateConfiguration(logger);

            // ensure this runs in the grain context, wait for it to complete
            scheduler.QueueTask(CreateSystemGrains, catalog.SchedulingContext)
            .WaitWithThrow(initTimeout);
            if (logger.IsVerbose)
            {
                logger.Verbose("System grains created successfully.");
            }

            // Initialize storage providers once we have a basic silo runtime environment operating
            storageProviderManager = new StorageProviderManager(grainFactory, Services);
            scheduler.QueueTask(
                () => storageProviderManager.LoadStorageProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
            .WaitWithThrow(initTimeout);
            catalog.SetStorageManager(storageProviderManager);
            allSiloProviders.AddRange(storageProviderManager.GetProviders());
            if (logger.IsVerbose)
            {
                logger.Verbose("Storage provider manager created successfully.");
            }

            // Load and init stream providers before silo becomes active
            var siloStreamProviderManager = (StreamProviderManager)grainRuntime.StreamProviderManager;

            scheduler.QueueTask(
                () => siloStreamProviderManager.LoadStreamProviders(GlobalConfig.ProviderConfigurations, SiloProviderRuntime.Instance),
                providerManagerSystemTarget.SchedulingContext)
            .WaitWithThrow(initTimeout);
            InsideRuntimeClient.Current.CurrentStreamProviderManager = siloStreamProviderManager;
            allSiloProviders.AddRange(siloStreamProviderManager.GetProviders());
            if (logger.IsVerbose)
            {
                logger.Verbose("Stream provider manager created successfully.");
            }

            ISchedulingContext statusOracleContext = ((SystemTarget)LocalSiloStatusOracle).SchedulingContext;

            bool waitForPrimaryToStart = globalConfig.PrimaryNodeIsRequired && siloType != SiloType.Primary;

            if (waitForPrimaryToStart) // only in MembershipTableGrain case.
            {
                scheduler.QueueTask(() => membershipFactory.WaitForTableToInit(membershipTable), statusOracleContext)
                .WaitWithThrow(initTimeout);
            }
            scheduler.QueueTask(() => membershipTable.InitializeMembershipTable(GlobalConfig, true, LogManager.GetLogger(membershipTable.GetType().Name)), statusOracleContext)
            .WaitWithThrow(initTimeout);

            scheduler.QueueTask(() => LocalSiloStatusOracle.Start(), statusOracleContext)
            .WaitWithThrow(initTimeout);
            if (logger.IsVerbose)
            {
                logger.Verbose("Local silo status oracle created successfully.");
            }
            scheduler.QueueTask(LocalSiloStatusOracle.BecomeActive, statusOracleContext)
            .WaitWithThrow(initTimeout);
            if (logger.IsVerbose)
            {
                logger.Verbose("Local silo status oracle became active successfully.");
            }

            //if running in multi cluster scenario, start the MultiClusterNetwork Oracle
            if (GlobalConfig.HasMultiClusterNetwork)
            {
                logger.Info("Creating multicluster oracle with my ServiceId={0} and ClusterId={1}.",
                            GlobalConfig.ServiceId, GlobalConfig.ClusterId);

                ISchedulingContext clusterStatusContext = ((SystemTarget)multiClusterOracle).SchedulingContext;
                scheduler.QueueTask(() => multiClusterOracle.Start(LocalSiloStatusOracle), clusterStatusContext)
                .WaitWithThrow(initTimeout);
                if (logger.IsVerbose)
                {
                    logger.Verbose("multicluster oracle created successfully.");
                }
            }

            try
            {
                siloStatistics.Start(LocalConfig);
                if (logger.IsVerbose)
                {
                    logger.Verbose("Silo statistics manager started successfully.");
                }

                // Finally, initialize the deployment load collector, for grains with load-based placement
                scheduler.QueueTask(DeploymentLoadPublisher.Instance.Start, DeploymentLoadPublisher.Instance.SchedulingContext)
                .WaitWithThrow(initTimeout);
                if (logger.IsVerbose)
                {
                    logger.Verbose("Silo deployment load publisher started successfully.");
                }

                // Start background timer tick to watch for platform execution stalls, such as when GC kicks in
                platformWatchdog = new Watchdog(nodeConfig.StatisticsLogWriteInterval, healthCheckParticipants);
                platformWatchdog.Start();
                if (logger.IsVerbose)
                {
                    logger.Verbose("Silo platform watchdog started successfully.");
                }

                if (reminderService != null)
                {
                    // so, we have the view of the membership in the consistentRingProvider. We can start the reminder service
                    scheduler.QueueTask(reminderService.Start, ((SystemTarget)reminderService).SchedulingContext)
                    .WaitWithThrow(initTimeout);
                    if (logger.IsVerbose)
                    {
                        logger.Verbose("Reminder service started successfully.");
                    }
                }

                bootstrapProviderManager = new BootstrapProviderManager();
                scheduler.QueueTask(
                    () => bootstrapProviderManager.LoadAppBootstrapProviders(GlobalConfig.ProviderConfigurations),
                    providerManagerSystemTarget.SchedulingContext)
                .WaitWithThrow(initTimeout);
                BootstrapProviders = bootstrapProviderManager.GetProviders(); // Data hook for testing & diagnotics
                allSiloProviders.AddRange(BootstrapProviders);

                if (logger.IsVerbose)
                {
                    logger.Verbose("App bootstrap calls done successfully.");
                }

                // Start stream providers after silo is active (so the pulling agents don't start sending messages before silo is active).
                // also after bootstrap provider started so bootstrap provider can initialize everything stream before events from this silo arrive.
                scheduler.QueueTask(siloStreamProviderManager.StartStreamProviders, providerManagerSystemTarget.SchedulingContext)
                .WaitWithThrow(initTimeout);
                if (logger.IsVerbose)
                {
                    logger.Verbose("Stream providers started successfully.");
                }

                // Now that we're active, we can start the gateway
                var mc = messageCenter as MessageCenter;
                if (mc != null)
                {
                    mc.StartGateway(clientRegistrar);
                }
                if (logger.IsVerbose)
                {
                    logger.Verbose("Message gateway service started successfully.");
                }

                SystemStatus.Current = SystemStatus.Running;
            }
            catch (Exception exc)
            {
                SafeExecute(() => logger.Error(ErrorCode.Runtime_Error_100330, String.Format("Error starting silo {0}. Going to FastKill().", SiloAddress), exc));
                FastKill(); // if failed after Membership became active, mark itself as dead in Membership abale.
                throw;
            }
            if (logger.IsVerbose)
            {
                logger.Verbose("Silo.Start complete: System status = {0}", SystemStatus.Current);
            }
        }