public async Task <TResult> Perform <TResult>(Func <IGrainContext, Task <TResult> > fn, RequestMode mode = RequestMode.Unspecified) { try { await _sm.WaitAsync(); try { if (_status == ActivationStatus.Deactivated) { throw new DeactivatedException(); } if (_ctx == null) { _ctx = await _ctxFac(); await _runner.Perform(async() => { await _ctx.Grain.OnActivateAsync(); _status = ActivationStatus.Activated; return(true); }, RequestMode.Isolated); } } finally { _sm.Release(); } return(await _runner.Perform(() => fn(_ctx), mode)); } catch (RequestRunnerClosedException) { throw new DeactivatedException(); } }
// Only required if you have work groups flagged by a context that is not a WorkGroupingContext public WorkItemGroup RegisterWorkContext(IGrainContext context) { if (context is null) { return(null); } var wg = new WorkItemGroup( this, context, this.workItemGroupLogger, this.activationTaskSchedulerLogger, this.cancellationTokenSource.Token, this.schedulerStatistics, this.statisticsOptions); if (context is SystemTarget systemTarget) { systemTarget.WorkItemGroup = wg; } if (context is ActivationData activation) { activation.WorkItemGroup = wg; } workgroupDirectory.TryAdd(context, wg); return(wg); }
/// <summary> /// Receive a new message: /// - validate order constraints, queue (or possibly redirect) if out of order /// - validate transactions constraints /// - invoke handler if ready, otherwise enqueue for later invocation /// </summary> public void ReceiveMessage(IGrainContext target, Message message) { var activation = (ActivationData)target; _messagingTrace.OnDispatcherReceiveMessage(message); // Don't process messages that have already timed out if (message.IsExpired) { MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message); _messagingTrace.OnDropExpiredMessage(message, MessagingStatisticsGroup.Phase.Dispatch); return; } if (message.Direction == Message.Directions.Response) { ReceiveResponse(message, activation); } else // Request or OneWay { if (activation.State == ActivationState.Valid) { _activationCollector.TryRescheduleCollection(activation); } // Silo is always capable to accept a new request. It's up to the activation to handle its internal state. // If activation is shutting down, it will queue and later forward this request. ReceiveRequest(message, activation); } }
private ILogViewAdaptorFactory SetupLogConsistencyProvider(IGrainContext activationContext) { var attr = this.GetType().GetCustomAttributes <LogConsistencyProviderAttribute>(true).FirstOrDefault(); ILogViewAdaptorFactory defaultFactory = attr != null ? this.ServiceProvider.GetServiceByName <ILogViewAdaptorFactory>(attr.ProviderName) : this.ServiceProvider.GetService <ILogViewAdaptorFactory>(); if (attr != null && defaultFactory == null) { var errMsg = $"Cannot find consistency provider with Name={attr.ProviderName} for grain type {this.GetType().FullName}"; throw new BadGrainStorageConfigException(errMsg); } // use default if none found defaultFactory = defaultFactory ?? this.DefaultAdaptorFactory; if (defaultFactory == null) { var errMsg = $"No log consistency provider found loading grain type {this.GetType().FullName}"; throw new BadGrainStorageConfigException(errMsg); } ; return(defaultFactory); }
internal static WorkItemGroup CreateWorkItemGroupForTesting( IGrainContext context, ILoggerFactory loggerFactory) { var services = new ServiceCollection(); services.AddOptions(); services.AddLogging(); services.AddSingleton <SchedulerStatisticsGroup>(); services.AddSingleton <StageAnalysisStatisticsGroup>(); services.AddSingleton(loggerFactory); services.Configure <SchedulingOptions>(options => { options.DelayWarningThreshold = TimeSpan.FromMilliseconds(100); options.ActivationSchedulingQuantum = TimeSpan.FromMilliseconds(100); options.TurnWarningLengthThreshold = TimeSpan.FromMilliseconds(100); options.StoppedActivationWarningInterval = TimeSpan.FromMilliseconds(200); }); var s = services.BuildServiceProvider(); var result = new WorkItemGroup( context, s.GetRequiredService <ILogger <WorkItemGroup> >(), s.GetRequiredService <ILogger <ActivationTaskScheduler> >(), s.GetRequiredService <SchedulerStatisticsGroup>(), s.GetRequiredService <IOptions <StatisticsOptions> >(), s.GetRequiredService <IOptions <SchedulingOptions> >()); return(result); }
public override Task OnActivateAsync() { _context = RuntimeContext.CurrentGrainContext; _scheduler = TaskScheduler.Current; executing = false; return(base.OnActivateAsync()); }
public TransactionalStateStorageProviderWrapper(IGrainStorage grainStorage, string stateName, IGrainContext context, ILoggerFactory loggerFactory) { this.grainStorage = grainStorage; this.context = context; this.loggerFactory = loggerFactory; this.stateName = stateName; }
private object Create(IGrainContext context, MethodInfo genericCreate, IPersistentStateConfiguration config) { IPersistentStateFactory factory = context.ActivationServices.GetRequiredService <IPersistentStateFactory>(); object[] args = new object[] { context, config }; return(genericCreate.Invoke(factory, args)); }
/// <summary> /// Used by generated code for <see cref="IGrainExtension" /> interfaces. /// </summary> /// <typeparam name="TComponent"> /// The type of the component to get. /// </typeparam> /// <param name="context"> /// The grain context. /// </param> /// <returns> /// The grain extension. /// </returns> public static TComponent GetGrainExtension <TComponent>(this IGrainContext context) where TComponent : IGrainExtension { var binder = context.GetComponent <IGrainExtensionBinder>(); return(binder.GetExtension <TComponent>()); }
internal int RegisterWorkItemGroup(string workItemGroupName, IGrainContext 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 = 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); } bool ReportPerWorkItemStats(IGrainContext context) { return(context is ISystemTargetBase ? this.collectionLevel >= StatisticsLevel.Verbose2 : this.collectionLevel >= StatisticsLevel.Verbose3); } }
public ITransactionalStateStorage <TState> Create <TState>(string stateName, IGrainContext context) where TState : class, new() { var azureStateStorage = this.factory.Create <TState>(stateName, context); return(ActivatorUtilities.CreateInstance <FaultInjectionAzureTableTransactionStateStorage <TState> >( context.ActivationServices, azureStateStorage)); }
internal static OrleansTaskScheduler InitializeSchedulerForTesting( IGrainContext context, ILoggerFactory loggerFactory) { var services = new ServiceCollection(); services.AddOptions(); services.AddLogging(); services.AddSingleton <SchedulerStatisticsGroup>(); services.AddSingleton <StageAnalysisStatisticsGroup>(); services.AddSingleton(loggerFactory); services.Configure <SchedulingOptions>(options => { options.MaxActiveThreads = 4; options.DelayWarningThreshold = TimeSpan.FromMilliseconds(100); options.ActivationSchedulingQuantum = TimeSpan.FromMilliseconds(100); options.TurnWarningLengthThreshold = TimeSpan.FromMilliseconds(100); options.StoppedActivationWarningInterval = TimeSpan.FromMilliseconds(200); }); var serviceProvider = services.BuildServiceProvider(); var scheduler = ActivatorUtilities.CreateInstance <OrleansTaskScheduler>(serviceProvider); WorkItemGroup ignore = scheduler.RegisterWorkContext(context); return(scheduler); }
private void ThrowNoWorkItemGroup(IGrainContext context) { 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 Task QueueTask(this IGrainContext targetContext, Func <Task> taskFunc) { var workItem = new AsyncClosureWorkItem(taskFunc, targetContext); targetContext.Scheduler.QueueWorkItem(workItem); return(workItem.Task); }
private string MakePartitionKey(IGrainContext context, string stateName) { string grainKey = context.GrainReference.GrainId.ToString(); var key = $"{grainKey}_{this.clusterOptions.ServiceId}_{stateName}"; return(AzureTableUtils.SanitizeTableProperty(key)); }
public void QueueAction(Action action, IGrainContext context) { #if DEBUG if (logger.IsEnabled(LogLevel.Trace)) { logger.LogTrace("ScheduleTask on {Context}", context); } #endif var workItemGroup = GetWorkItemGroup(context); if (applicationTurnsStopped && (workItemGroup != null) && !workItemGroup.IsSystemGroup) { // Drop the task on the floor if it's an application work item and application turns are stopped logger.LogWarning((int)ErrorCode.SchedulerAppTurnsStopped_1, "Dropping task item {Task} on context {Context} because application turns are stopped", action, context); return; } if (workItemGroup?.TaskScheduler is TaskScheduler scheduler) { // This will make sure the TaskScheduler.Current is set correctly on any task that is created implicitly in the execution of this workItem. // We must wrap any work item in Task and enqueue it as a task to the right scheduler via Task.Start. Task t = new Task(action); t.Start(scheduler); } else { // Note that we do not use UnsafeQueueUserWorkItem here because we typically want to propagate execution context, // which includes async locals. #if NETCOREAPP ThreadPool.QueueUserWorkItem(ExecuteActionCallback, action, preferLocal: true); #else ThreadPool.QueueUserWorkItem(ExecuteAction, action); #endif } }
/// <inheritdoc/> public void Configure(IGrainContext context) { if (context.GrainInstance is IStreamSubscriptionObserver observer) { InstallStreamConsumerExtension(context, observer as IStreamSubscriptionObserver); } }
public override Task OnActivateAsync(CancellationToken cancellationToken) { _context = RuntimeContext.Current; _scheduler = TaskScheduler.Current; executing = false; return(base.OnActivateAsync(cancellationToken)); }
public ActivationCountBasedPlacementTestGrain( OverloadDetector overloadDetector, TestHooksHostEnvironmentStatistics hostEnvironmentStatistics, IOptions <LoadSheddingOptions> loadSheddingOptions, IGrainContext grainContext) : base(overloadDetector, hostEnvironmentStatistics, loadSheddingOptions, grainContext) { }
public override Task OnActivateAsync() { ThrowIfDeactivating(); context = RuntimeContext.Current; defaultTimer = this.RegisterTimer(Tick, DefaultTimerName, period, period); allTimers = new Dictionary <string, IDisposable>(); return(Task.CompletedTask); }
public IDisposable RegisterTimer(IGrainContext grainContext, Func <object, Task> asyncCallback, object state, TimeSpan dueTime, TimeSpan period) { var timer = GrainTimer.FromTaskCallback(this.timerLogger, asyncCallback, state, dueTime, period, grainContext: grainContext); grainContext?.GetComponent <IGrainTimerRegistry>().OnTimerCreated(timer); timer.Start(); return(timer); }
private static void SetupResourceFactory(IGrainContext context, string stateName, TransactionQueue <TState> queue) { // Add resources factory to the grain context context.RegisterResourceFactory <ITransactionalResource>(stateName, () => new TransactionalResource <TState>(queue)); // Add tm factory to the grain context context.RegisterResourceFactory <ITransactionManager>(stateName, () => new TransactionManager <TState>(queue)); }
internal void SetupResourceFactory(IGrainContext context, string stateName, TransactionQueue <TState> queue) { // Add resources factory to the grain context context.RegisterResourceFactory <ITransactionalResource>(stateName, () => new FaultInjectionTransactionalResource <TState>(this.faultInjector, FaultInjectionControl, new TransactionalResource <TState>(queue), context, logger, grainRuntime)); // Add tm factory to the grain context context.RegisterResourceFactory <ITransactionManager>(stateName, () => new FaultInjectionTransactionManager <TState>(this.faultInjector, FaultInjectionControl, new TransactionManager <TState>(queue), context, logger, grainRuntime)); }
/// <summary> /// Directly send a message to the transport without processing /// </summary> /// <param name="message"></param> /// <param name="sendingActivation"></param> public void TransportMessage(Message message, IGrainContext sendingActivation = null) { MarkSameCallChainMessageAsInterleaving(sendingActivation, message); if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace(ErrorCode.Dispatcher_Send_AddressedMessage, "Addressed message {0}", message); } Transport.SendMessage(message); }
public FaultInjectionTransactionManager(IControlledTransactionFaultInjector faultInjector, FaultInjectionControl faultInjectionControl, TransactionManager <TState> tm, IGrainContext activationContext, ILogger logger, IGrainRuntime grainRuntime) { this.grainRuntime = grainRuntime; this.tm = tm; this.faultInjectionControl = faultInjectionControl; this.logger = logger; this.context = activationContext; this.faultInjector = faultInjector; }
public void OnEnqueueMessageOnActivation(Message message, IGrainContext context) { if (this.IsEnabled(EnqueueMessageOnActivationEventName)) { this.Write(EnqueueMessageOnActivationEventName, message); } MessagingProcessingStatisticsGroup.OnImaMessageEnqueued(context); }
internal LocalObjectData(IAddressable obj, ObserverGrainId observerId, IGrainMethodInvoker invoker, IGrainContext rootGrainContext) { this.LocalObject = new WeakReference(obj); this.ObserverId = observerId; this.Invoker = invoker; this.Messages = new Queue <Message>(); this.Running = false; _rootGrainContext = rootGrainContext; }
public FaultInjectionTransactionalResource(IControlledTransactionFaultInjector faultInjector, FaultInjectionControl faultInjectionControl, TransactionalResource <TState> tResource, IGrainContext activationContext, ILogger logger, IGrainRuntime grainRuntime) { this.grainRuntime = grainRuntime; this.tResource = tResource; this.faultInjectionControl = faultInjectionControl; this.logger = logger; this.faultInjector = faultInjector; this.context = activationContext; }
public void DelayDeactivation(IGrainContext grainContext, TimeSpan timeSpan) { CheckRuntimeContext(grainContext); if (grainContext is not ICollectibleGrainContext collectibleContext) { throw new NotSupportedException($"Grain context {grainContext} does not implement {nameof(ICollectibleGrainContext)} and therefore {nameof(DelayDeactivation)} is not supported"); } collectibleContext.DelayDeactivation(timeSpan); }
public object[] CreateArguments(IGrainContext grainContext) { int i = 0; object[] results = new object[argumentFactorys.Count]; foreach (Factory <IGrainContext, object> argumentFactory in argumentFactorys) { results[i++] = argumentFactory(grainContext); } return(results); }