Ejemplo n.º 1
0
        internal async Task OnPostInvokeAsync(ActorBase actor, ActorMethodContext actorMethodContext)
        {
            this.ThrowIfClosed();
            await actor.OnPostActorMethodAsyncInternal(actorMethodContext);

            await SaveStateAsync(actor);
        }
Ejemplo n.º 2
0
        public Task <IServiceRemotingResponseMessageBody> InvokeAsync(ActorId actorId, int interfaceId, int methodId,
                                                                      string callContext,
                                                                      IServiceRemotingRequestMessageBody requestMsgBody,
                                                                      IServiceRemotingMessageBodyFactory remotingMessageBodyFactory,
                                                                      CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            this.ThrowIfClosed();

            var methodDispatcher   = this.actorService.MethodDispatcherMapV2.GetDispatcher(interfaceId, methodId);
            var actorMethodName    = methodDispatcher.GetMethodName(methodId);
            var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName);


            return(this.DispatchToActorAsync <IServiceRemotingResponseMessageBody>(
                       actorId: actorId,
                       actorMethodContext: actorMethodContext,
                       createIfRequired: true,
                       actorFunc:
                       (actor, innerCancellationToken) =>
                       this.ActorMethodDispatch(methodDispatcher, actor, interfaceId, methodId, requestMsgBody,
                                                remotingMessageBodyFactory,
                                                innerCancellationToken),
                       callContext: callContext,
                       timerCall: false,
                       cancellationToken: cancellationToken));
        }
Ejemplo n.º 3
0
        public Task <byte[]> InvokeAsync(
            ActorId actorId,
            int interfaceId,
            int methodId,
            string callContext,
            byte[] requestMsgBody,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            var methodDispatcher   = this.actorService.MethodDispatcherMap.GetDispatcher(interfaceId, methodId);
            var actorMethodName    = methodDispatcher.GetMethodName(methodId);
            var actorMethodContext = ActorMethodContext.CreateForActor(actorMethodName);

            var deserializationStartTime = DateTime.UtcNow;
            var requestBody = methodDispatcher.DeserializeRequestMessageBody(requestMsgBody);

            this.DiagnosticsEventManager.ActorRequestDeserializationFinish(deserializationStartTime);

            return(this.DispatchToActorAsync(
                       actorId: actorId,
                       actorMethodContext: actorMethodContext,
                       createIfRequired: true,
                       actorFunc:
                       (actor, innerCancellationToken) =>
                       this.ActorMethodDispatch(methodDispatcher, actor, interfaceId, methodId, requestBody, innerCancellationToken),
                       callContext: callContext,
                       timerCall: false,
                       cancellationToken: cancellationToken));
        }
Ejemplo n.º 4
0
 public Task <byte[]> DispatchToActorAsync(
     ActorId actorId,
     ActorMethodContext actorMethodContext,
     bool createIfRequired,
     Func <ActorBase, CancellationToken, Task <byte[]> > actorFunc,
     string callContext,
     bool timerCall,
     CancellationToken cancellationToken)
 {
     return(TaskDone <byte[]> .Done);
 }
Ejemplo n.º 5
0
 internal ActorManager(ActorService actorService)
 {
     this.actorService            = actorService;
     this.traceId                 = actorService.Context.TraceId;
     this.diagnosticsManager      = new DiagnosticsManager(actorService);
     this.diagnosticsEventManager = this.diagnosticsManager.DiagnosticsEventManager;
     this.eventManager            = new ActorEventManager(actorService.ActorTypeInformation);
     this.isClosed                = false;
     this.activeActors            = new ConcurrentDictionary <ActorId, ActorBase>();
     this.remindersByActorId      = new ConcurrentDictionary <ActorId, ConcurrentDictionary <string, ActorReminder> >();
     this.reminderMethodContext   = ActorMethodContext.CreateForReminder(ReceiveReminderMethodName);
     this.gcTimer                 = new Timer(this.RunGarbageCollection, null, Timeout.Infinite, Timeout.Infinite);
 }
Ejemplo n.º 6
0
        private async Task <T> DispatchToActorConcurrencyLockHeldAsync <T>(
            ActorId actorId,
            ActorMethodContext actorMethodContext,
            ActorBase actor,
            Func <ActorBase, CancellationToken, Task <T> > actorFunc,
            string callContext,
            CancellationToken cancellationToken)
        {
            var retval = default(T);

            // if this actor has been deleted or is a dummy actor, then calls must be made on new object.
            if (actor.MarkedForDeletion || actor.IsDummy)
            {
                // Deleted Actor, Method calls will be retried by Actor Proxy.
                throw new ActorDeletedException(string.Format(CultureInfo.CurrentCulture,
                                                              SR.ActorDeletedExceptionMessage, actorId));
            }

            this.ThrowIfClosed();

            // set the incoming callContext as the new logical call context, before
            // making calls to the actor, so that when the actor makes call this context
            // flows through
            ActorLogicalCallContext.Set(callContext);

            // initialize the actor if needed
            if (ShouldInitialize(actor))
            {
                await this.InitializeAsync(actor);
            }
            try
            {
                // invoke the function of the actor
                await this.OnPreInvokeAsync(actor, actorMethodContext);

                retval = await actorFunc.Invoke(actor, cancellationToken);

                await this.OnPostInvokeAsync(actor, actorMethodContext);
            }
            catch
            {
                actor.OnInvokeFailedInternal();
                throw;
            }

            return(retval);
        }
        public ActorTimer(
            ActorBase owner,
            Func <Object, Task> asyncCallback,
            object state,
            TimeSpan dueTime,
            TimeSpan period)
        {
            this.owner                 = owner;
            this.asyncCallback         = asyncCallback;
            this.callbackMethodContext = ActorMethodContext.CreateForTimer(this.asyncCallback.GetMethodInfo().Name);
            this.callbackState         = state;
            this.period                = period;
            this.dueTime               = dueTime;
            this.timer                 = new Timer(this.OnTimerCallback);

            this.ArmTimer(dueTime);
        }
Ejemplo n.º 8
0
 internal async Task OnPreInvokeAsync(ActorBase actor, ActorMethodContext actorMethodContext)
 {
     this.ThrowIfClosed();
     await actor.OnPreActorMethodAsyncInternal(actorMethodContext);
 }
Ejemplo n.º 9
0
        public async Task <byte[]> DispatchToActorAsync(
            ActorId actorId,
            ActorMethodContext actorMethodContext,
            bool createIfRequired,
            Func <ActorBase, CancellationToken, Task <byte[]> > actorFunc,
            string callContext,
            bool timerCall,
            CancellationToken cancellationToken)
        {
            ExceptionDispatchInfo exceptionInfo = null;
            Exception             exception     = null;

            byte[] retval = null;


            // get activeActor from the activeActors table
            using (var actorUseScope = this.GetActor(actorId, createIfRequired, timerCall))
            {
                var actor = actorUseScope.Actor;

                //
                // START: CRITICAL CODE
                //
                // Emit diagnostic info - before acquiring actor lock
                var      lockAcquireStartTime  = this.DiagnosticsEventManager.AcquireActorLockStart(actor);
                DateTime?lockAcquireFinishTime = null;
                try
                {
                    await actor.ConcurrencyLock.Acquire(callContext, (async innerActor => await this.HandleDirtyStateAsync(innerActor)), cancellationToken);
                }
                catch
                {
                    // Emit diagnostic info - failed to acquire actor lock
                    this.DiagnosticsEventManager.AcquireActorLockFailed(actor);
                    throw;
                }
                //
                // WARNING: DO NOT PUT ANY CODE BETWEEN CONCURRENCY LOCK ACQUIRE AND TRY
                // THE LOCK NEEDS TO BE RELEASED IF THERE IS ANY EXCEPTION
                //
                try
                {
                    // Emit diagnostic info - after acquiring actor lock
                    lockAcquireFinishTime = this.DiagnosticsEventManager.AcquireActorLockFinish(actor, lockAcquireStartTime);

                    retval = await this.DispatchToActorConcurrencyLockHeldAsync(actorId, actorMethodContext, actor, actorFunc, callContext, cancellationToken);
                }
                catch (Exception e)
                {
                    exception = e;
                    try
                    {
                        exceptionInfo = ExceptionDispatchInfo.Capture(e);
                    }
                    catch
                    {
                        // ignored
                    }
                }
                //
                // WARNING: DO NOT PUT ANY CODE BELOW BEFORE THE LOCK IS RELEASED
                // BECAUSE WE ARE NOT INSIDE A TRY-CATCH BLOCK
                //
                // signal that current execution is finished on this actor
                // since there is no call pending or this was the first actor call in the callContext
                await actor.ConcurrencyLock.ReleaseContext(callContext);

                // Emit diagnostic info - after releasing actor lock
                this.DiagnosticsEventManager.ReleaseActorLock(lockAcquireFinishTime);

                //
                // END: CRITICAL CODE
                //

                if (exceptionInfo != null)
                {
                    exceptionInfo.Throw();
                }
                else if (exception != null)
                {
                    throw exception;
                }

                return(retval);
            }
        }
Ejemplo n.º 10
0
 internal Task OnPostActorMethodAsyncInternal(ActorMethodContext actorMethodContext)
 {
     return(this.OnPostActorMethodAsync(actorMethodContext));
 }
Ejemplo n.º 11
0
 /// <summary>
 /// This method is invoked by actor runtime an actor method has finished execution. Override this method
 /// for performing any actions after an actor method has finished execution.
 /// </summary>
 /// <param name="actorMethodContext">
 /// An <see cref="ActorMethodContext"/> describing the method that was invoked by actor runtime prior to this method.
 /// </param>
 /// <returns>
 /// A <see cref="Task">Task</see> representing post-actor-method operation.
 /// </returns>
 /// /// <remarks>
 /// This method is invoked by actor runtime prior to:
 /// <list type="bullet">
 /// <item><description>Invoking an actor interface method when a client request comes.</description></item>
 /// <item><description>Invoking a method on <see cref="IRemindable"/> interface when a reminder fires.</description></item>
 /// <item><description>Invoking a timer callback when timer fires.</description></item>
 /// </list>
 /// </remarks>
 protected virtual Task OnPostActorMethodAsync(ActorMethodContext actorMethodContext)
 {
     return(TaskDone.Done);
 }