internal async Task OnPostInvokeAsync(ActorBase actor, ActorMethodContext actorMethodContext) { this.ThrowIfClosed(); await actor.OnPostActorMethodAsyncInternal(actorMethodContext); await SaveStateAsync(actor); }
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)); }
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)); }
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); }
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); }
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); }
internal async Task OnPreInvokeAsync(ActorBase actor, ActorMethodContext actorMethodContext) { this.ThrowIfClosed(); await actor.OnPreActorMethodAsyncInternal(actorMethodContext); }
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); } }
internal Task OnPostActorMethodAsyncInternal(ActorMethodContext actorMethodContext) { return(this.OnPostActorMethodAsync(actorMethodContext)); }
/// <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); }