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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
 public override Task OnActivateAsync()
 {
     _context   = RuntimeContext.CurrentGrainContext;
     _scheduler = TaskScheduler.Current;
     executing  = false;
     return(base.OnActivateAsync());
 }
Exemple #7
0
 public TransactionalStateStorageProviderWrapper(IGrainStorage grainStorage, string stateName, IGrainContext context, ILoggerFactory loggerFactory)
 {
     this.grainStorage  = grainStorage;
     this.context       = context;
     this.loggerFactory = loggerFactory;
     this.stateName     = stateName;
 }
Exemple #8
0
        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));
        }
Exemple #12
0
        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
            }
        }
Exemple #17
0
 /// <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));
 }
Exemple #19
0
 public ActivationCountBasedPlacementTestGrain(
     OverloadDetector overloadDetector,
     TestHooksHostEnvironmentStatistics hostEnvironmentStatistics,
     IOptions <LoadSheddingOptions> loadSheddingOptions,
     IGrainContext grainContext)
     : base(overloadDetector, hostEnvironmentStatistics, loadSheddingOptions, grainContext)
 {
 }
Exemple #20
0
 public override Task OnActivateAsync()
 {
     ThrowIfDeactivating();
     context      = RuntimeContext.Current;
     defaultTimer = this.RegisterTimer(Tick, DefaultTimerName, period, period);
     allTimers    = new Dictionary <string, IDisposable>();
     return(Task.CompletedTask);
 }
Exemple #21
0
        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);
        }
Exemple #22
0
        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);
 }
Exemple #25
0
 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;
 }
Exemple #26
0
        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;
 }
Exemple #28
0
 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;
 }
Exemple #29
0
        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);
            }