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; }
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; }
/// <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 }
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(); }
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(); } }
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 }
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); } }
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)); }
public async Task ExecAsync(Func <Task> asyncFunction, ISchedulingContext context) { await Task.Run(asyncFunction); // No grain context on client - run on .NET thread pool }
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); }
public async Task ExecAsync(Func <Task> asyncFunction, ISchedulingContext context, string activityName) { // Schedule call back to grain context await OrleansTaskScheduler.Instance.QueueNamedTask(asyncFunction, context, activityName); }
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(); } }
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"); }
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); }
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); }
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); }
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(); } }
public async Task ExecAsync(Func<Task> asyncFunction, ISchedulingContext context, string activityName) { // Schedule call back to grain context await OrleansTaskScheduler.Instance.QueueNamedTask(asyncFunction, context, activityName); }
// 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); }
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 }
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); }
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); } }
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); }
public async Task ExecAsync(Func<Task> asyncFunction, ISchedulingContext context) { // Schedule call back to grain context await OrleansTaskScheduler.Instance.RunOrQueueTask(asyncFunction, context); }
// 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; }
internal static Task WrapWorkItemAsTask(IWorkItem todo, ISchedulingContext context, TaskScheduler sched) { var task = new Task(state => RunWorkItemTask(todo, sched), context); return task; }
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); }
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)); }
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); } }
public bool Equals(ISchedulingContext other) { return AreSame(other); }
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); }
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); }
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); }
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(); }
/// <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 }
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)); }
// 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(); }); } }
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; } }
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; }
internal static bool ReportPerWorkItemStats(ISchedulingContext schedulingContext) { return SchedulingUtils.IsSystemPriorityContext(schedulingContext) ? IsVerbose2 : IsVerbose3; }
public async Task ExecAction(Action action, ISchedulingContext context) { // Schedule call back to grain context await OrleansTaskScheduler.Instance.QueueAction(action, context); }