internal void RunMessagePump(ActivationData activation) { // Note: this method must be called while holding lock (activation) #if DEBUG // This is a hot code path, so using #if to remove diags from Release version // Note: Caller already holds lock on activation if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace(ErrorCode.Dispatcher_ActivationEndedTurn_Waiting, "RunMessagePump {0}: Activation={1}", activation.ActivationId, activation.DumpStatus()); } #endif // don't run any messages if activation is not ready or deactivating if (activation.State != ActivationState.Valid) return; bool runLoop; do { runLoop = false; var nextMessage = activation.PeekNextWaitingMessage(); if (nextMessage == null) continue; if (!ActivationMayAcceptRequest(activation, nextMessage)) continue; activation.DequeueNextWaitingMessage(); // we might be over-writing an already running read only request. HandleIncomingRequest(nextMessage, activation); runLoop = true; } while (runLoop); }
/// <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.IsEnabled(LogLevel.Trace)) { logger.Trace(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> /// Enqueue message for local handling after transaction completes /// </summary> /// <param name="message"></param> /// <param name="targetActivation"></param> private void EnqueueRequest(Message message, ActivationData targetActivation) { var overloadException = targetActivation.CheckOverloaded(logger); if (overloadException != null) { MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Overload2"); RejectMessage(message, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + targetActivation); return; } switch (targetActivation.EnqueueMessage(message)) { case ActivationData.EnqueueMessageResult.Success: // Great, nothing to do break; case ActivationData.EnqueueMessageResult.ErrorInvalidActivation: ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest"); break; case ActivationData.EnqueueMessageResult.ErrorActivateFailed: ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest", rejectMessages: true); break; case ActivationData.EnqueueMessageResult.ErrorStuckActivation: // Avoid any new call to this activation catalog.DeactivateStuckActivation(targetActivation); ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest - blocked grain"); break; default: throw new ArgumentOutOfRangeException(); } // Dont count this as end of processing. The message will come back after queueing via HandleIncomingRequest. #if DEBUG // This is a hot code path, so using #if to remove diags from Release version // Note: Caller already holds lock on activation if (logger.IsEnabled(LogLevel.Trace)) { logger.Trace(ErrorCode.Dispatcher_EnqueueMessage, "EnqueueMessage for {0}: targetActivation={1}", message.TargetActivation, targetActivation.DumpStatus()); } #endif }
/// <summary> /// Enqueue message for local handling after transaction completes /// </summary> /// <param name="message"></param> /// <param name="targetActivation"></param> private void EnqueueRequest(Message message, ActivationData targetActivation) { var overloadException = targetActivation.CheckOverloaded(logger); if (overloadException != null) { MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Overload2"); RejectMessage(message, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + targetActivation); return; } if (Message.WriteMessagingTraces) { message.AddTimestamp(Message.LifecycleTag.EnqueueWaiting); } bool enqueuedOk = targetActivation.EnqueueMessage(message); if (!enqueuedOk) { ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest"); } // Dont count this as end of processing. The message will come back after queueing via HandleIncomingRequest. #if DEBUG // This is a hot code path, so using #if to remove diags from Release version // Note: Caller already holds lock on activation if (logger.IsVerbose2) { logger.Verbose2(ErrorCode.Dispatcher_EnqueueMessage, "EnqueueMessage for {0}: targetActivation={1}", message.TargetActivation, targetActivation.DumpStatus()); } #endif }
internal void RunMessagePump(ActivationData activation) { // Note: this method must be called while holding lock (activation) #if DEBUG // This is a hot code path, so using #if to remove diags from Release version // Note: Caller already holds lock on activation if (logger.IsVerbose2) { logger.Verbose2(ErrorCode.Dispatcher_ActivationEndedTurn_Waiting, "RunMessagePump {0}: Activation={1}", activation.ActivationId, activation.DumpStatus()); } #endif // don't run any messages if activation is not ready or deactivating if (!activation.State.Equals(ActivationState.Valid)) return; bool runLoop; do { runLoop = false; var nextMessage = activation.PeekNextWaitingMessage(); if (nextMessage == null) continue; if (!ActivationMayAcceptRequest(activation, nextMessage)) continue; activation.DequeueNextWaitingMessage(); // we might be over-writing an already running read only request. HandleIncomingRequest(nextMessage, activation); runLoop = true; } while (runLoop); }
/// <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> /// Enqueue message for local handling after transaction completes /// </summary> /// <param name="message"></param> /// <param name="targetActivation"></param> private void EnqueueRequest(Message message, ActivationData targetActivation) { var overloadException = targetActivation.CheckOverloaded(logger); if (overloadException != null) { MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Overload2"); RejectMessage(message, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + targetActivation); return; } bool enqueuedOk = targetActivation.EnqueueMessage(message); if (!enqueuedOk) { ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest"); } // Dont count this as end of processing. The message will come back after queueing via HandleIncomingRequest. #if DEBUG // This is a hot code path, so using #if to remove diags from Release version // Note: Caller already holds lock on activation if (logger.IsVerbose2) logger.Verbose2(ErrorCode.Dispatcher_EnqueueMessage, "EnqueueMessage for {0}: targetActivation={1}", message.TargetActivation, targetActivation.DumpStatus()); #endif }
/// <summary> /// Enqueue message for local handling after transaction completes /// </summary> /// <param name="message"></param> /// <param name="targetActivation"></param> private void EnqueueRequest(Message message, ActivationData targetActivation) { var overloadException = targetActivation.CheckOverloaded(logger); if (overloadException != null) { MessagingProcessingStatisticsGroup.OnDispatcherMessageProcessedError(message, "Overload2"); RejectMessage(message, Message.RejectionTypes.Overloaded, overloadException, "Target activation is overloaded " + targetActivation); return; } switch (targetActivation.EnqueueMessage(message)) { case ActivationData.EnqueueMessageResult.Success: // Great, nothing to do break; case ActivationData.EnqueueMessageResult.ErrorInvalidActivation: ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest"); break; case ActivationData.EnqueueMessageResult.ErrorStuckActivation: // Avoid any new call to this activation catalog.DeactivateStuckActivation(targetActivation); ProcessRequestToInvalidActivation(message, targetActivation.Address, targetActivation.ForwardingAddress, "EnqueueRequest - blocked grain"); break; default: throw new ArgumentOutOfRangeException(); } // Dont count this as end of processing. The message will come back after queueing via HandleIncomingRequest. #if DEBUG // This is a hot code path, so using #if to remove diags from Release version // Note: Caller already holds lock on activation if (logger.IsVerbose2) logger.Verbose2(ErrorCode.Dispatcher_EnqueueMessage, "EnqueueMessage for {0}: targetActivation={1}", message.TargetActivation, targetActivation.DumpStatus()); #endif }