Example #1
0
 public override Task OnActivateAsync()
 {
     logger = (Logger)this.GetLogger("TimerGrain_" + base.Data.Address.ToString());
     context = RuntimeContext.Current.ActivationContext;
     defaultTimer = this.RegisterTimer(Tick, DefaultTimerName, TimeSpan.Zero, period);
     allTimers = new Dictionary<string, IDisposable>();
     return TaskDone.Done;
 }
Example #2
0
 internal static OrleansTaskScheduler InitializeSchedulerForTesting(ISchedulingContext context)
 {
     StatisticsCollector.StatisticsCollectionLevel = StatisticsLevel.Info;
     SchedulerStatisticsGroup.Init();
     var scheduler = new OrleansTaskScheduler(4);
     scheduler.Start();
     WorkItemGroup ignore = scheduler.RegisterWorkContext(context);
     return scheduler;
 }
Example #3
0
        /// <summary>
        /// Create a new TaskWorkItem for running the specified Task on the specified scheduler.
        /// </summary>
        /// <param name="sched">Scheduler to execute this Task action. A value of null means use the Orleans system scheduler.</param>
        /// <param name="t">Task to be performed</param>
        /// <param name="context">Execution context</param>
        internal TaskWorkItem(ITaskScheduler sched, Task t, ISchedulingContext context)
        {
            scheduler = sched;
            task = t;
            SchedulingContext = context;
#if DEBUG
            if (logger.IsVerbose2) logger.Verbose2("Created TaskWorkItem {0} for Id={1} State={2} with Status={3} Scheduler={4}",
                Name, task.Id, (task.AsyncState == null) ? "null" : task.AsyncState.ToString(), task.Status, scheduler);
#endif
        }
Example #4
0
 public InvokeWorkItem(ActivationData activation, Message message, ISchedulingContext context)
 {
     this.activation = activation;
     this.message = message;
     SchedulingContext = context;
     if (activation == null || activation.GrainInstance==null)
     {
         var str = String.Format("Creating InvokeWorkItem with bad activation: {0}. Message: {1}", activation, message);
         logger.Warn(ErrorCode.SchedulerNullActivation, str);
         throw new ArgumentException(str);
     }
     activation.IncrementInFlightCount();
 }
Example #5
0
 private async Task TimerTick(object state, ISchedulingContext context)
 {
     if (TimerAlreadyStopped)
         return;
     try
     {
         await RuntimeClient.Current.ExecAsync(() => ForwardToAsyncCallback(state), context, Name);
     }
     catch (InvalidSchedulingContextException exc)
     {
         logger.Error(ErrorCode.Timer_InvalidContext,
             string.Format("Caught an InvalidSchedulingContextException on timer {0}, context is {1}. Going to dispose this timer!",
                 GetFullName(), context), exc);
         DisposeTimer();
     }
 }
Example #6
0
 internal void CheckSchedulingContextValidity(ISchedulingContext context)
 {
     if (context == null)
     {
         throw new InvalidSchedulingContextException(
             "CheckSchedulingContextValidity was called on a null SchedulingContext."
              + "Please make sure you are not trying to create a Timer from outside Orleans Task Scheduler, "
              + "which will be the case if you create it inside Task.Run.");
     }
     GetWorkItemGroup(context); // GetWorkItemGroup throws for Invalid context
 }
Example #7
0
        private async Task OnRuntimeGrainServicesStart(CancellationToken ct)
        {
            var stopWatch = Stopwatch.StartNew();

            await StartAsyncTaskWithPerfAnalysis("Init transaction agent", InitTransactionAgent, stopWatch);

            async Task InitTransactionAgent()
            {
                ITransactionAgent  transactionAgent        = this.Services.GetRequiredService <ITransactionAgent>();
                ISchedulingContext transactionAgentContext = (transactionAgent as SystemTarget)?.SchedulingContext;
                await scheduler.QueueTask(transactionAgent.Start, transactionAgentContext)
                .WithTimeout(initTimeout, $"Starting TransactionAgent failed due to timeout {initTimeout}");
            }

            // Load and init grain services before silo becomes active.
            await StartAsyncTaskWithPerfAnalysis("Init grain services",
                                                 () => CreateGrainServices(), stopWatch);

            this.membershipOracleContext = (this.membershipOracle as SystemTarget)?.SchedulingContext ??
                                           this.fallbackScheduler.SchedulingContext;

            await StartAsyncTaskWithPerfAnalysis("Starting local silo status oracle", StartMembershipOracle, stopWatch);

            async Task StartMembershipOracle()
            {
                await scheduler.QueueTask(() => this.membershipOracle.Start(), this.membershipOracleContext)
                .WithTimeout(initTimeout, $"Starting MembershipOracle failed due to timeout {initTimeout}");

                logger.Debug("Local silo status oracle created successfully.");
            }

            var versionStore = Services.GetService <IVersionStore>();

            await StartAsyncTaskWithPerfAnalysis("Init type manager", () => scheduler
                                                 .QueueTask(() => this.typeManager.Initialize(versionStore), this.typeManager.SchedulingContext)
                                                 .WithTimeout(this.initTimeout, $"TypeManager Initializing failed due to timeout {initTimeout}"), stopWatch);

            //if running in multi cluster scenario, start the MultiClusterNetwork Oracle
            if (this.multiClusterOracle != null)
            {
                await StartAsyncTaskWithPerfAnalysis("Start multicluster oracle", StartMultiClusterOracle, stopWatch);

                async Task StartMultiClusterOracle()
                {
                    logger.Info("Starting multicluster oracle with my ServiceId={0} and ClusterId={1}.",
                                this.clusterOptions.ServiceId, this.clusterOptions.ClusterId);

                    this.multiClusterOracleContext = (multiClusterOracle as SystemTarget)?.SchedulingContext ??
                                                     this.fallbackScheduler.SchedulingContext;
                    await scheduler.QueueTask(() => multiClusterOracle.Start(), multiClusterOracleContext)
                    .WithTimeout(initTimeout, $"Starting MultiClusterOracle failed due to timeout {initTimeout}");

                    logger.Debug("multicluster oracle created successfully.");
                }
            }

            try
            {
                StatisticsOptions statisticsOptions = Services.GetRequiredService <IOptions <StatisticsOptions> >().Value;
                StartTaskWithPerfAnalysis("Start silo statistics", () => this.siloStatistics.Start(statisticsOptions), stopWatch);
                logger.Debug("Silo statistics manager started successfully.");

                // Finally, initialize the deployment load collector, for grains with load-based placement
                await StartAsyncTaskWithPerfAnalysis("Start deployment load collector", StartDeploymentLoadCollector, stopWatch);

                async Task StartDeploymentLoadCollector()
                {
                    var deploymentLoadPublisher = Services.GetRequiredService <DeploymentLoadPublisher>();

                    await this.scheduler.QueueTask(deploymentLoadPublisher.Start, deploymentLoadPublisher.SchedulingContext)
                    .WithTimeout(this.initTimeout, $"Starting DeploymentLoadPublisher failed due to timeout {initTimeout}");

                    logger.Debug("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(statisticsOptions.LogWriteInterval, this.healthCheckParticipants, this.executorService, this.loggerFactory);
                this.platformWatchdog.Start();
                if (this.logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug("Silo platform watchdog started successfully.");
                }
            }
            catch (Exception exc)
            {
                this.SafeExecute(() => this.logger.Error(ErrorCode.Runtime_Error_100330, String.Format("Error starting silo {0}. Going to FastKill().", this.SiloAddress), exc));
                throw;
            }
            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.Debug("Silo.Start complete: System status = {0}", this.SystemStatus);
            }
        }
Example #8
0
 public bool Equals(ISchedulingContext other)
 {
     return(AreSame(other));
 }
 public TaskScheduler GetTaskScheduler(ISchedulingContext context)
 {
     if (context == null)
         return this;
     
     WorkItemGroup workGroup;
     return workgroupDirectory.TryGetValue(context, out workGroup) ? (TaskScheduler) workGroup.TaskRunner : this;
 }
        // Only required if you have work groups flagged by a context that is not a WorkGroupingContext
        public WorkItemGroup RegisterWorkContext(ISchedulingContext context)
        {
            if (context == null) return null;

            var wg = new WorkItemGroup(this, context);
            workgroupDirectory.TryAdd(context, wg);
            return wg;
        }
 public bool Equals(ISchedulingContext other)
 {
     return(base.Equals(other));
 }
Example #12
0
 public async Task ExecAsync(Func <Task> asyncFunction, ISchedulingContext context)
 {
     await Task.Run(asyncFunction); // No grain context on client - run on .NET thread pool
 }
Example #13
0
 private void UnhandledException(ISchedulingContext context, Exception exception)
 {
     logger.Error(ErrorCode.Runtime_Error_100007, String.Format("OutsideRuntimeClient caught an UnobservedException."), exception);
     logger.Assert(ErrorCode.Runtime_Error_100008, context == null, "context should be not null only inside OrleansRuntime and not on the client.");
 }
 private bool TryGetCurrentActivationData(ISchedulingContext context, out ActivationData activationData)
 {
     activationData = (context as SchedulingContext)?.Activation;
     return(activationData != null);
 }
Example #15
0
 public async Task ExecAsync(Func <Task> asyncFunction, ISchedulingContext context, string activityName)
 {
     // Schedule call back to grain context
     await OrleansTaskScheduler.Instance.QueueNamedTask(asyncFunction, context, activityName);
 }
Example #16
0
 internal static bool ReportPerWorkItemStats(ISchedulingContext schedulingContext)
 {
     return(SchedulingUtils.IsSystemPriorityContext(schedulingContext) ? IsVerbose2 : IsVerbose3);
 }
 internal static void OnImaMessageEnqueued(ISchedulingContext context)
 {
     if (context == null)
     {
         imaEnqueuedByContext[0].Increment();
     }
     else if (context.ContextType == SchedulingContextType.SystemTarget)
     {
         imaEnqueuedByContext[1].Increment();
     }
     else if (context.ContextType == SchedulingContextType.Activation)
     {
         imaEnqueuedByContext[2].Increment();
     }
 }
Example #18
0
 private static void CheckRuntimeContext(ISchedulingContext context)
 {
     Assert.IsNotNull(RuntimeContext.Current, "Runtime context should not be null");
     Assert.IsNotNull(RuntimeContext.Current.ActivationContext, "Activation context should not be null");
     Assert.AreEqual(context, RuntimeContext.Current.ActivationContext, "Activation context");
 }
Example #19
0
        private void EnqueueReceiveMessage(Message msg, ActivationData targetActivation, ISchedulingContext context)
        {
            MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context);

            if (targetActivation != null)
            {
                targetActivation.IncrementEnqueuedOnDispatcherCount();
            }

            scheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                try
                {
                    dispatcher.ReceiveMessage(msg);
                }
                finally
                {
                    if (targetActivation != null)
                    {
                        targetActivation.DecrementEnqueuedOnDispatcherCount();
                    }
                }
            },
                                                        () => "Dispatcher.ReceiveMessage"), context);
        }
Example #20
0
        private async Task OnRuntimeServicesStart(CancellationToken ct)
        {
            //TODO: Setup all (or as many as possible) of the class started in this call to work directly with lifecyce

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

            implicitStreamSubscriberTable.InitImplicitStreamSubscribers(grainTypeManager.GrainClassTypeData.Select(t => t.Value.Type).ToArray());

            var siloProviderRuntime = Services.GetRequiredService <SiloProviderRuntime>();

            runtimeClient.CurrentStreamProviderRuntime = siloProviderRuntime;
            statisticsProviderManager = this.Services.GetRequiredService <StatisticsProviderManager>();
            string statsProviderName = await statisticsProviderManager.LoadProvider(GlobalConfig.ProviderConfigurations)
                                       .WithTimeout(initTimeout);

            if (statsProviderName != null)
            {
                LocalConfig.StatisticsProviderName = statsProviderName;
            }

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

            await siloStatistics.SetSiloMetricsTableDataManager(this, LocalConfig).WithTimeout(initTimeout);


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

            await InjectDependencies();

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

            // Initialize storage providers once we have a basic silo runtime environment operating
            storageProviderManager = this.Services.GetRequiredService <StorageProviderManager>();
            await scheduler.QueueTask(
                () => storageProviderManager.LoadStorageProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
            .WithTimeout(initTimeout);

            ITransactionAgent  transactionAgent        = this.Services.GetRequiredService <ITransactionAgent>();
            ISchedulingContext transactionAgentContext = (transactionAgent as SystemTarget)?.SchedulingContext;
            await scheduler.QueueTask(transactionAgent.Start, transactionAgentContext)
            .WithTimeout(initTimeout);

            var versionStore = Services.GetService <IVersionStore>() as GrainVersionStore;

            versionStore?.SetStorageManager(storageProviderManager);
            logger.Debug("Storage provider manager created successfully.");

            // Initialize log consistency providers once we have a basic silo runtime environment operating
            logConsistencyProviderManager = this.Services.GetRequiredService <LogConsistencyProviderManager>();
            await scheduler.QueueTask(
                () => logConsistencyProviderManager.LoadLogConsistencyProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
            .WithTimeout(initTimeout);

            logger.Debug("Log consistency provider manager created successfully.");

            // Load and init stream providers before silo becomes active
            var siloStreamProviderManager = (StreamProviderManager)this.Services.GetRequiredService <IStreamProviderManager>();
            await scheduler.QueueTask(
                () => siloStreamProviderManager.LoadStreamProviders(GlobalConfig.ProviderConfigurations, siloProviderRuntime),
                providerManagerSystemTarget.SchedulingContext)
            .WithTimeout(initTimeout);

            runtimeClient.CurrentStreamProviderManager = siloStreamProviderManager;
            logger.Debug("Stream provider manager created successfully.");

            // Load and init grain services before silo becomes active.
            await CreateGrainServices(GlobalConfig.GrainServiceConfigurations);

            this.membershipOracleContext = (this.membershipOracle as SystemTarget)?.SchedulingContext ??
                                           this.providerManagerSystemTarget.SchedulingContext;
            await scheduler.QueueTask(() => this.membershipOracle.Start(), this.membershipOracleContext)
            .WithTimeout(initTimeout);

            logger.Debug("Local silo status oracle created successfully.");
            await scheduler.QueueTask(this.membershipOracle.BecomeActive, this.membershipOracleContext)
            .WithTimeout(initTimeout);

            logger.Debug("Local silo status oracle became active successfully.");
            await scheduler.QueueTask(() => this.typeManager.Initialize(versionStore), this.typeManager.SchedulingContext)
            .WithTimeout(this.initTimeout);

            //if running in multi cluster scenario, start the MultiClusterNetwork Oracle
            if (this.multiClusterOracle != null)
            {
                logger.Info("Starting multicluster oracle with my ServiceId={0} and ClusterId={1}.",
                            this.siloOptions.ServiceId, this.siloOptions.ClusterId);

                this.multiClusterOracleContext = (multiClusterOracle as SystemTarget)?.SchedulingContext ??
                                                 this.providerManagerSystemTarget.SchedulingContext;
                await scheduler.QueueTask(() => multiClusterOracle.Start(), multiClusterOracleContext)
                .WithTimeout(initTimeout);

                logger.Debug("multicluster oracle created successfully.");
            }

            try
            {
                this.siloStatistics.Start(this.LocalConfig);
                logger.Debug("Silo statistics manager started successfully.");

                // Finally, initialize the deployment load collector, for grains with load-based placement
                var deploymentLoadPublisher = Services.GetRequiredService <DeploymentLoadPublisher>();
                await this.scheduler.QueueTask(deploymentLoadPublisher.Start, deploymentLoadPublisher.SchedulingContext)
                .WithTimeout(this.initTimeout);

                logger.Debug("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.executorService, this.loggerFactory);
                this.platformWatchdog.Start();
                if (this.logger.IsEnabled(LogLevel.Debug))
                {
                    logger.Debug("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.reminderServiceContext = (this.reminderService as SystemTarget)?.SchedulingContext ??
                                                  this.providerManagerSystemTarget.SchedulingContext;
                    await this.scheduler.QueueTask(this.reminderService.Start, this.reminderServiceContext)
                    .WithTimeout(this.initTimeout);

                    this.logger.Debug("Reminder service started successfully.");
                }

                this.bootstrapProviderManager = this.Services.GetRequiredService <BootstrapProviderManager>();
                await this.scheduler.QueueTask(
                    () => this.bootstrapProviderManager.LoadAppBootstrapProviders(siloProviderRuntime, this.GlobalConfig.ProviderConfigurations),
                    this.providerManagerSystemTarget.SchedulingContext)
                .WithTimeout(this.initTimeout);

                this.BootstrapProviders = this.bootstrapProviderManager.GetProviders(); // Data hook for testing & diagnotics

                logger.Debug("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.
                await this.scheduler.QueueTask(siloStreamProviderManager.StartStreamProviders, this.providerManagerSystemTarget.SchedulingContext)
                .WithTimeout(this.initTimeout);

                logger.Debug("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>());
                logger.Debug("Message gateway service started successfully.");

                this.SystemStatus = 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));
                throw;
            }
            if (logger.IsEnabled(LogLevel.Debug))
            {
                logger.Debug("Silo.Start complete: System status = {0}", this.SystemStatus);
            }
        }
 public bool Equals(ISchedulingContext other)
 {
     return base.Equals(other);
 }
Example #22
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);
            statisticsProviderManager = new StatisticsProviderManager("Statistics", SiloProviderRuntime.Instance);
            string statsProviderName = statisticsProviderManager.LoadProvider(GlobalConfig.ProviderConfigurations)
                                       .WaitForResultWithThrow(initTimeout);

            if (statsProviderName != null)
            {
                LocalConfig.StatisticsProviderName = statsProviderName;
            }

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

            membershipOracle = membershipFactory.CreateMembershipOracle(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();
            scheduler.QueueTask(
                () => storageProviderManager.LoadStorageProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
            .WaitWithThrow(initTimeout);
            catalog.SetStorageManager(storageProviderManager);
            if (logger.IsVerbose)
            {
                logger.Verbose("Storage provider manager created successfully.");
            }

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

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

            ISchedulingContext statusOracleContext = ((SystemTarget)LocalSiloStatusOracle).SchedulingContext;
            bool waitForPrimaryToStart             = globalConfig.PrimaryNodeIsRequired && siloType != SiloType.Primary;

            scheduler.QueueTask(() => LocalSiloStatusOracle.Start(waitForPrimaryToStart), 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.");
            }

            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.");
                }

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

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

                var bootstrapProviderManager = new BootstrapProviderManager();
                scheduler.QueueTask(
                    () => bootstrapProviderManager.LoadAppBootstrapProviders(GlobalConfig.ProviderConfigurations),
                    providerManagerSystemTarget.SchedulingContext)
                .WaitWithThrow(initTimeout);
                BootstrapProviders = bootstrapProviderManager.GetProviders(); // Data hook for testing & diagnotics
                if (logger.IsVerbose)
                {
                    logger.Verbose("App bootstrap calls done 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.");
                }

                scheduler.QueueTask(clientRegistrar.Start, clientRegistrar.SchedulingContext)
                .WaitWithThrow(initTimeout);
                if (logger.IsVerbose)
                {
                    logger.Verbose("Client registrar 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);
            }
        }
        // public for testing only -- should be private, otherwise
        public WorkItemGroup GetWorkItemGroup(ISchedulingContext context)
        {
            if (context == null)
                return null;
           
            WorkItemGroup workGroup;
            if(workgroupDirectory.TryGetValue(context, out workGroup))
                return workGroup;

            var error = String.Format("QueueWorkItem was called on a non-null context {0} but there is no valid WorkItemGroup for it.", context);
            logger.Error(ErrorCode.SchedulerQueueWorkItemWrongContext, error);
            throw new InvalidSchedulingContextException(error);
        }
Example #24
0
        internal static void OnTurnExecutionStartsByWorkGroup(int workItemGroup, int workerThread, ISchedulingContext context)
        {
            turnsExecutedStartTotal.Increment();
            turnsExecutedPerWorkItemGroup[workItemGroup].Increment();


            if (context == null)
            {
                throw new ArgumentException(String.Format("Cannot execute null context work item on work item group {0}.", workItemGroup));
            }

            if (context.ContextType == SchedulingContextType.SystemTarget)
            {
                turnsExecutedByAllWorkItemGroupsTotalSystem.Increment();
                turnsExecutedPerWorkerThreadSystemTurns[workerThread].Increment();
                turnsExecutedByAllWorkerThreadsTotalSystemTurns.Increment();
            }
            else if (context.ContextType == SchedulingContextType.Activation)
            {
                turnsExecutedByAllWorkItemGroupsTotalApplicationTurns.Increment();
                turnsExecutedPerWorkerThreadApplicationTurns[workerThread].Increment();
                turnsExecutedByAllWorkerThreadsTotalApplicationTurns.Increment();
            }
        }
Example #25
0
 public async Task ExecAsync(Func<Task> asyncFunction, ISchedulingContext context, string activityName)
 {
     // Schedule call back to grain context
     await OrleansTaskScheduler.Instance.QueueNamedTask(asyncFunction, context, activityName);
 }
Example #26
0
 // AddressableContext is the one that can send messages (Activation and SystemTarget)
 // null context and SystemThread and not addressable.
 internal static bool IsAddressableContext(ISchedulingContext context)
 {
     return(context != null && context.ContextType != SchedulingContextType.SystemThread);
 }
Example #27
0
 public async Task ExecAsync(Func<Task> asyncFunction, ISchedulingContext context, string activityName)
 {
     await Task.Run(asyncFunction); // No grain context on client - run on .NET thread pool
 }
Example #28
0
 internal static bool IsSystemPriorityContext(ISchedulingContext context)
 {
     // System Priorit Context are either associated with the (null) context, system target or regular (non low priority) system thread.
     // Both System targets, system thread and normal grains have OrleansContext instances, of the appropriate type (based on SchedulingContext.ContextType).
     return(context == null || context.IsSystemPriorityContext);
 }
Example #29
0
 private void UnobservedExceptionHandler(ISchedulingContext context, Exception exception)
 {
     var schedulingContext = context as SchedulingContext;
     if (schedulingContext == null)
     {
         if (context == null)
             logger.Error(ErrorCode.Runtime_Error_100102, "Silo caught an UnobservedException with context==null.", exception);
         else
             logger.Error(ErrorCode.Runtime_Error_100103, String.Format("Silo caught an UnobservedException with context of type different than OrleansContext. The type of the context is {0}. The context is {1}",
                 context.GetType(), context), exception);
     }
     else
     {
         logger.Error(ErrorCode.Runtime_Error_100104, String.Format("Silo caught an UnobservedException thrown by {0}.", schedulingContext.Activation), exception);
     }   
 }
Example #30
0
 internal static bool IsSystemContext(ISchedulingContext context)
 {
     // System Context are either associated with the (null) context, system target or any (low and high priority) system thread.
     // Both System targets, system thread and normal grains have OrleansContext instances, of the appropriate type (based on SchedulingContext.ContextType).
     return(context == null || context.ContextType == SchedulingContextType.SystemTarget || context.ContextType == SchedulingContextType.SystemThread);
 }
Example #31
0
 public async Task ExecAsync(Func<Task> asyncFunction, ISchedulingContext context)
 {
     // Schedule call back to grain context
     await OrleansTaskScheduler.Instance.RunOrQueueTask(asyncFunction, context);
 }
Example #32
0
 // public for testing only -- should be private, otherwise
 public WorkItemGroup GetWorkItemGroup(ISchedulingContext context)
 {
     WorkItemGroup workGroup = null;
     if (context != null)
         workgroupDirectory.TryGetValue(context, out workGroup);
     
     return workGroup;
 }
Example #33
0
 internal static Task WrapWorkItemAsTask(IWorkItem todo, ISchedulingContext context, TaskScheduler sched)
 {
     var task = new Task(state => RunWorkItemTask(todo, sched), context);
     return task;
 }
Example #34
0
        private void EnqueueReceiveMessage(Message msg, ActivationData targetActivation, ISchedulingContext context)
        {
            MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context);

            if (targetActivation != null) targetActivation.IncrementEnqueuedOnDispatcherCount();

            scheduler.QueueWorkItem(new ClosureWorkItem(() =>
            {
                try
                {
                    dispatcher.ReceiveMessage(msg);
                }
                finally
                {
                    if (targetActivation != null) targetActivation.DecrementEnqueuedOnDispatcherCount();
                }
            },
            () => "Dispatcher.ReceiveMessage"), context);
        }
Example #35
0
        internal static Task RunOrQueueTask(this OrleansTaskScheduler scheduler, Func <Task> taskFunc, ISchedulingContext targetContext)
        {
            var currentContext = RuntimeContext.CurrentActivationContext;

            if (SchedulingUtils.IsAddressableContext(currentContext) &&
                currentContext.Equals(targetContext))
            {
                try
                {
                    return(taskFunc());
                }
                catch (Exception exc)
                {
                    return(Task.FromResult(exc));
                }
            }

            return(scheduler.QueueTask(taskFunc, targetContext));
        }
Example #36
0
        private void DoStart()
        {
            lock (lockable)
            {
                if (!this.SystemStatus.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.", this.SystemStatus));
                }

                this.SystemStatus = SystemStatus.Starting;
            }

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

            // Hook up to receive notification of process exit / Ctrl-C events
            AppDomain.CurrentDomain.ProcessExit += HandleProcessExit;
            if (GlobalConfig.FastKillOnCancelKeyPress)
            {
                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 = this.Services.GetRequiredService <StatisticsProviderManager>();
            string statsProviderName = statisticsProviderManager.LoadProvider(GlobalConfig.ProviderConfigurations)
                                       .WaitForResultWithThrow(initTimeout);

            if (statsProviderName != null)
            {
                LocalConfig.StatisticsProviderName = statsProviderName;
            }

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


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

            InjectDependencies();

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

            // Initialize storage providers once we have a basic silo runtime environment operating
            storageProviderManager = this.Services.GetRequiredService <StorageProviderManager>();
            scheduler.QueueTask(
                () => storageProviderManager.LoadStorageProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
            .WaitWithThrow(initTimeout);

            ITransactionAgent  transactionAgent        = this.Services.GetRequiredService <ITransactionAgent>();
            ISchedulingContext transactionAgentContext = (transactionAgent as SystemTarget)?.SchedulingContext;

            scheduler.QueueTask(transactionAgent.Start, transactionAgentContext)
            .WaitWithThrow(initTimeout);

            var versionStore = Services.GetService <IVersionStore>() as GrainVersionStore;

            versionStore?.SetStorageManager(storageProviderManager);
            if (logger.IsVerbose)
            {
                logger.Verbose("Storage provider manager created successfully.");
            }

            // Initialize log consistency providers once we have a basic silo runtime environment operating
            logConsistencyProviderManager = this.Services.GetRequiredService <LogConsistencyProviderManager>();
            scheduler.QueueTask(
                () => logConsistencyProviderManager.LoadLogConsistencyProviders(GlobalConfig.ProviderConfigurations),
                providerManagerSystemTarget.SchedulingContext)
            .WaitWithThrow(initTimeout);
            if (logger.IsVerbose)
            {
                logger.Verbose("Log consistency 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;
            if (logger.IsVerbose)
            {
                logger.Verbose("Stream provider manager created successfully.");
            }

            // Load and init grain services before silo becomes active.
            CreateGrainServices(GlobalConfig.GrainServiceConfigurations);

            this.membershipOracleContext = (this.membershipOracle as SystemTarget)?.SchedulingContext ??
                                           this.providerManagerSystemTarget.SchedulingContext;
            scheduler.QueueTask(() => this.membershipOracle.Start(), this.membershipOracleContext)
            .WaitWithThrow(initTimeout);
            if (logger.IsVerbose)
            {
                logger.Verbose("Local silo status oracle created successfully.");
            }
            scheduler.QueueTask(this.membershipOracle.BecomeActive, this.membershipOracleContext)
            .WaitWithThrow(initTimeout);
            if (logger.IsVerbose)
            {
                logger.Verbose("Local silo status oracle became active successfully.");
            }
            scheduler.QueueTask(() => this.typeManager.Initialize(versionStore), this.typeManager.SchedulingContext)
            .WaitWithThrow(this.initTimeout);

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

                this.multiClusterOracleContext = (multiClusterOracle as SystemTarget)?.SchedulingContext ??
                                                 this.providerManagerSystemTarget.SchedulingContext;
                scheduler.QueueTask(() => multiClusterOracle.Start(), multiClusterOracleContext)
                .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.reminderServiceContext = (this.reminderService as SystemTarget)?.SchedulingContext ??
                                                  this.providerManagerSystemTarget.SchedulingContext;
                    this.scheduler.QueueTask(this.reminderService.Start, this.reminderServiceContext)
                    .WaitWithThrow(this.initTimeout);
                    if (this.logger.IsVerbose)
                    {
                        this.logger.Verbose("Reminder service started successfully.");
                    }
                }

                this.bootstrapProviderManager = this.Services.GetRequiredService <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

                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.");
                }

                this.SystemStatus = 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}", this.SystemStatus);
            }
        }
Example #37
0
 public bool Equals(ISchedulingContext other)
 {
     return AreSame(other);
 }
Example #38
0
        internal static Task <T> QueueTask <T>(this OrleansTaskScheduler scheduler, Func <Task <T> > taskFunc, ISchedulingContext targetContext)
        {
            var         resolver  = new TaskCompletionSource <T>();
            Func <Task> asyncFunc =
                async() =>
            {
                try
                {
                    T result = await taskFunc();

                    resolver.TrySetResult(result);
                }
                catch (Exception exc)
                {
                    resolver.TrySetException(exc);
                }
            };

            // it appears that it's not important that we fire-and-forget asyncFunc() because we wait on the
            scheduler.QueueWorkItem(new ClosureWorkItem(() => asyncFunc().Ignore()), targetContext);
            return(resolver.Task);
        }
Example #39
0
        internal static Task QueueTask(this OrleansTaskScheduler scheduler, Func <Task> taskFunc, ISchedulingContext targetContext)
        {
            var         resolver  = new TaskCompletionSource <bool>();
            Func <Task> asyncFunc =
                async() =>
            {
                try
                {
                    await taskFunc();

                    resolver.TrySetResult(true);
                }
                catch (Exception exc)
                {
                    resolver.TrySetException(exc);
                }
            };

            scheduler.QueueWorkItem(new ClosureWorkItem(() => asyncFunc().Ignore()), targetContext);
            return(resolver.Task);
        }
Example #40
0
        internal static Task QueueAction(this OrleansTaskScheduler scheduler, Action action, ISchedulingContext targetContext)
        {
            var    resolver = new TaskCompletionSource <bool>();
            Action syncFunc =
                () =>
            {
                try
                {
                    action();
                    resolver.TrySetResult(true);
                }
                catch (Exception exc)
                {
                    resolver.TrySetException(exc);
                }
            };

            scheduler.QueueWorkItem(new ClosureWorkItem(() => syncFunc()), targetContext);
            return(resolver.Task);
        }
 private static void CheckRuntimeContext(ISchedulingContext context)
 {
     Assert.IsNotNull(RuntimeContext.Current, "Runtime context should not be null");
     Assert.IsNotNull(RuntimeContext.Current.ActivationContext, "Activation context should not be null");
     Assert.AreEqual(context, RuntimeContext.Current.ActivationContext, "Activation context");
 }
 public async Task ExecAsync(Func <Task> asyncFunction, ISchedulingContext context)
 {
     // Schedule call back to grain context
     await OrleansTaskScheduler.Instance.RunOrQueueTask(asyncFunction, context);
 }
        // Enqueue a work item to a given context
        public void QueueWorkItem(IWorkItem workItem, ISchedulingContext context)
        {
#if DEBUG
            if (logger.IsVerbose2) logger.Verbose2("QueueWorkItem " + context);
#endif
            if (workItem is TaskWorkItem)
            {
                var error = String.Format("QueueWorkItem was called on OrleansTaskScheduler for TaskWorkItem {0} on Context {1}."
                    + " Should only call OrleansTaskScheduler.QueueWorkItem on WorkItems that are NOT TaskWorkItem. Tasks should be queued to the scheduler via QueueTask call.",
                    workItem.ToString(), context);
                logger.Error(ErrorCode.SchedulerQueueWorkItemWrongCall, error);
                throw new InvalidOperationException(error);
            }

            var workItemGroup = GetWorkItemGroup(context);
            if (applicationTurnsStopped && (workItemGroup != null) && !workItemGroup.IsSystem)
            {
                // Drop the task on the floor if it's an application work item and application turns are stopped
                var msg = string.Format("Dropping work item {0} because applicaiton turns are stopped", workItem);
                logger.Warn(ErrorCode.SchedulerAppTurnsStopped, msg);
                return;
            }

            workItem.SchedulingContext = context;

            // We must wrap any work item in Task and enqueue it as a task to the right scheduler via Task.Start.
            // This will make sure the TaskScheduler.Current is set correctly on any task that is created implicitly in the execution of this workItem.
            if (workItemGroup == null)
            {
                Task t = TaskSchedulerUtils.WrapWorkItemAsTask(workItem, context, this);
                t.Start(this);
            }
            else
            {
                // Create Task wrapper for this work item
                Task t = TaskSchedulerUtils.WrapWorkItemAsTask(workItem, context, workItemGroup.TaskRunner);
                t.Start(workItemGroup.TaskRunner);
            }
        }
 private static void CheckRuntimeContext(ISchedulingContext context)
 {
     Assert.NotNull(RuntimeContext.Current);                          // Runtime context should not be null
     Assert.NotNull(RuntimeContext.Current.ActivationContext);        // Activation context should not be null
     Assert.Equal(context, RuntimeContext.Current.ActivationContext); // "Activation context"
 }
        // Only required if you have work groups flagged by a context that is not a WorkGroupingContext
        public void UnregisterWorkContext(ISchedulingContext context)
        {
            if (context == null) return;

            WorkItemGroup workGroup;
            if (workgroupDirectory.TryRemove(context, out workGroup))
                workGroup.Stop();
        }
Example #46
0
 /// <summary>
 /// Execute a closure ensuring that it has a runtime context (e.g. to send messages from an arbitrary thread)
 /// </summary>
 /// <param name="scheduler"></param>
 /// <param name="action"></param>
 /// <param name="targetContext"></param>
 internal static Task RunOrQueueAction(this OrleansTaskScheduler scheduler, Action action, ISchedulingContext targetContext)
 {
     return(scheduler.RunOrQueueTask(() =>
     {
         action();
         return TaskDone.Done;
     }, targetContext));
 }
 internal void CheckSchedulingContextValidity(ISchedulingContext context)
 {
     if (context == null)
     {
         throw new InvalidSchedulingContextException("CheckSchedulingContextValidity was called on a null SchedulingContext.");
     }
     GetWorkItemGroup(context); // GetWorkItemGroup throws for Invalid context
 }
Example #48
0
        internal static Task <T> RunOrQueueTask <T>(this OrleansTaskScheduler scheduler, Func <Task <T> > taskFunc, ISchedulingContext targetContext)
        {
            ISchedulingContext currentContext = RuntimeContext.CurrentActivationContext;

            if (SchedulingUtils.IsAddressableContext(currentContext) &&
                currentContext.Equals(targetContext))
            {
                try
                {
                    return(taskFunc());
                }
                catch (Exception exc)
                {
                    var resolver = new TaskCompletionSource <T>();
                    resolver.TrySetException(exc);
                    return(resolver.Task);
                }
            }

            return(scheduler.QueueTask(taskFunc, targetContext));
        }
Example #49
0
        // This is the maximum number of waiting threads (blocked in WaitForResponse) allowed
        // per ActivationWorker. An attempt to wait when there are already too many threads waiting
        // will result in a TooManyWaitersException being thrown.
        //private static readonly int MaxWaitingThreads = 500;


        internal WorkItemGroup(OrleansTaskScheduler sched, ISchedulingContext schedulingContext)
        {
            masterScheduler = sched;
            SchedulingContext = schedulingContext;
            state = WorkGroupStatus.Waiting;
            workItems = new Queue<ActivationTask>();
            lockable = new Object();
            totalItemsEnQueued = 0;
            totalItemsProcessed = 0;
            totalQueuingDelay = TimeSpan.Zero;
            quantumExpirations = 0;
            TaskRunner = new ActivationTaskScheduler(this);
            
            log = IsSystemPriority ? LogManager.GetLogger("Scheduler." + Name + ".WorkItemGroup", LoggerType.Runtime) : appLogger;
      
            if (StatisticsCollector.CollectShedulerQueuesStats)
            {
                queueTracking = new QueueTrackingStatistic("Scheduler." + SchedulingContext.Name);
                queueTracking.OnStartExecution();
            }

            if (StatisticsCollector.CollectPerWorkItemStats)
            {
                workItemGroupStatisticsNumber = SchedulerStatisticsGroup.RegisterWorkItemGroup(SchedulingContext.Name, SchedulingContext,
                    () =>
                    {
                        var sb = new StringBuilder();
                        lock (lockable)
                        {
                                    
                            sb.Append("QueueLength = " + WorkItemCount);
                            sb.Append(String.Format(", State = {0}", state));
                            if (state == WorkGroupStatus.Runnable)
                                sb.Append(String.Format("; oldest item is {0} old", workItems.Count >= 0 ? workItems.Peek().ToString() : "null"));
                        }
                        return sb.ToString();
                    });
            }
        }
        internal static void OnTurnExecutionStartsByWorkGroup(int workItemGroup, int workerThread, ISchedulingContext context)
        {
            turnsExecutedStartTotal.Increment();
            turnsExecutedPerWorkItemGroup[workItemGroup].Increment();
            

            if (context == null)
            {
                throw new ArgumentException(String.Format("Cannot execute null context work item on work item group {0}.", workItemGroup));
            }

            if (context.ContextType == SchedulingContextType.SystemTarget)
            {
                turnsExecutedByAllWorkItemGroupsTotalSystem.Increment();
                turnsExecutedPerWorkerThreadSystemTurns[workerThread].Increment();
                turnsExecutedByAllWorkerThreadsTotalSystemTurns.Increment();
            }
            else if (context.ContextType == SchedulingContextType.Activation)
            {
                turnsExecutedByAllWorkItemGroupsTotalApplicationTurns.Increment();
                turnsExecutedPerWorkerThreadApplicationTurns[workerThread].Increment();
                turnsExecutedByAllWorkerThreadsTotalApplicationTurns.Increment();
            }
        }
Example #51
0
 public override Task OnActivateAsync()
 {
     logger = this.GetLogger("TimerCallGrain_" + base.Data.Address);
     context = RuntimeContext.Current.ActivationContext;
     activationTaskScheduler = TaskScheduler.Current;
     return TaskDone.Done;
 }
 internal static int RegisterWorkItemGroup(string workItemGroupName, ISchedulingContext context, Func<string> statusGetter)
 {
     lock (lockable)
     {
         int i = workItemGroupCounter;
         workItemGroupCounter++;
         if (i == turnsExecutedPerWorkItemGroup.Length)
         {
             // need to resize the array
             Array.Resize(ref turnsExecutedPerWorkItemGroup, 2 * turnsExecutedPerWorkItemGroup.Length);
             Array.Resize(ref workItemGroupStatuses, 2 * workItemGroupStatuses.Length);
         }
         CounterStorage storage =  StatisticsCollector.ReportPerWorkItemStats(context) ? CounterStorage.LogAndTable : CounterStorage.DontStore;
         turnsExecutedPerWorkItemGroup[i] = CounterStatistic.FindOrCreate(new StatisticName(StatisticNames.SCHEDULER_ACTIVATION_TURNSEXECUTED_PERACTIVATION, workItemGroupName), storage);
         workItemGroupStatuses[i] = StringValueStatistic.FindOrCreate(new StatisticName(StatisticNames.SCHEDULER_ACTIVATION_STATUS_PERACTIVATION, workItemGroupName), statusGetter, storage);
         return i;
     }
 }
Example #53
0
 private void UnhandledException(ISchedulingContext context, Exception exception)
 {
     logger.Error(ErrorCode.Runtime_Error_100007, String.Format("OutsideRuntimeClient caught an UnobservedException."), exception);
     logger.Assert(ErrorCode.Runtime_Error_100008, context == null, "context should be not null only inside OrleansRuntime and not on the client.");
 }
Example #54
0
 internal static void SetExecutionContext(ISchedulingContext shedContext, TaskScheduler scheduler)
 {
     if (context == null) throw new InvalidOperationException("SetExecutionContext called on unexpected non-WorkerPool thread");
     context.ActivationContext = shedContext;
     context.Scheduler = scheduler;
 }
Example #55
0
 internal static bool ReportPerWorkItemStats(ISchedulingContext schedulingContext)
 {
     return SchedulingUtils.IsSystemPriorityContext(schedulingContext) ? IsVerbose2 : IsVerbose3;
 }
Example #56
0
 public async Task ExecAction(Action action, ISchedulingContext context)
 {
     // Schedule call back to grain context
     await OrleansTaskScheduler.Instance.QueueAction(action, context);
 }