/// <summary> /// Invoked when an activation has finished a transaction and may be ready for additional transactions /// </summary> /// <param name="activation">The activation that has just completed processing this message</param> /// <param name="message">The message that has just completed processing. /// This will be <c>null</c> for the case of completion of Activate/Deactivate calls.</param> internal void OnActivationCompletedRequest(ActivationData activation, Message message) { lock (activation) { #if DEBUG // This is a hot code path, so using #if to remove diags from Release version if (logger.IsVerbose2) { logger.Verbose2(ErrorCode.Dispatcher_OnActivationCompletedRequest_Waiting, "OnActivationCompletedRequest {0}: Activation={1}", activation.ActivationId, activation.DumpStatus()); } #endif activation.ResetRunning(message); // ensure inactive callbacks get run even with transactions disabled if (!activation.IsCurrentlyExecuting) { activation.RunOnInactive(); } // Run message pump to see if there is a new request arrived to be processed RunMessagePump(activation); } }
/// <summary> /// Invoked when an activation has finished a transaction and may be ready for additional transactions /// </summary> /// <param name="activation">The activation that has just completed processing this message</param> /// <param name="message">The message that has just completed processing. /// This will be <c>null</c> for the case of completion of Activate/Deactivate calls.</param> internal void OnActivationCompletedRequest(ActivationData activation, Message message) { lock (activation) { #if DEBUG // This is a hot code path, so using #if to remove diags from Release version if (logger.IsVerbose2) { logger.Verbose2(ErrorCode.Dispatcher_OnActivationCompletedRequest_Waiting, "OnActivationCompletedRequest {0}: Activation={1}", activation.ActivationId, activation.DumpStatus()); } #endif activation.ResetRunning(message); // ensure inactive callbacks get run even with transactions disabled if (!activation.IsCurrentlyExecuting) activation.RunOnInactive(); // Run message pump to see if there is a new request arrived to be processed RunMessagePump(activation); } }
private async Task CallGrainActivate(ActivationData activation) { var grainTypeName = activation.GrainInstanceType.FullName; // Note: This call is being made from within Scheduler.Queue wrapper, so we are already executing on worker thread if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_BeforeCallingActivate, "About to call {1} grain's OnActivateAsync() method {0}", activation, grainTypeName); // Call OnActivateAsync inline, but within try-catch wrapper to safely capture any exceptions thrown from called function try { await activation.GrainInstance.OnActivateAsync(); if (logger.IsVerbose) logger.Verbose(ErrorCode.Catalog_AfterCallingActivate, "Returned from calling {1} grain's OnActivateAsync() method {0}", activation, grainTypeName); lock (activation) { if (activation.State == ActivationState.Activating) { activation.SetState(ActivationState.Valid); // Activate calls on this activation are finished } if (!activation.IsCurrentlyExecuting) { activation.RunOnInactive(); } // Run message pump to see if there is a new request is queued to be processed dispatcher.RunMessagePump(activation); } } catch (Exception exc) { logger.Error(ErrorCode.Catalog_ErrorCallingActivate, string.Format("Error calling grain's AsyncActivate method - Grain type = {1} Activation = {0}", activation, grainTypeName), exc); activation.SetState(ActivationState.Invalid); // Mark this activation as unusable activationsFailedToActivate.Increment(); throw; } }