private static IGrainMethodInvoker GetGrainMethodInvoker(IAddressable target, IInvokable invokable, Message message, InvokeMethodRequest request) { var invoker = invokable.GetInvoker(request.InterfaceId, message.GenericGrainType); if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = new StackTrace().ToString(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } return(invoker); }
private bool TryInstallExtension(int interfaceId, IInvokable invokable, string genericGrainType, ref IGrainMethodInvoker invoker) { ActivationData activationData = GetCurrentActivationData(); IGrainExtension extension = activationData.ActivationServices.GetServiceByKey <int, IGrainExtension>(interfaceId); if (extension == null) { return(false); } if (!TryAddExtension(extension)) { return(false); } // Get the newly installed invoker for the grain extension. invoker = invokable.GetInvoker(typeManager, interfaceId, genericGrainType); return(true); }
public async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Invoke); return; } RequestContext.Import(message.RequestContextData); if (Config.Globals.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContext.ExportToMessage(message); } object resultObject; try { var request = (InvokeMethodRequest)message.GetDeserializedBody(this.SerializationManager); if (request.Arguments != null) { CancellationSourcesExtension.RegisterCancellationTokens(target, request, logger, this); } var invoker = invokable.GetInvoker(typeManager, request.InterfaceId, message.GenericGrainType); if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = Utils.GetStackTrace(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } #pragma warning disable 618 var invokeInterceptor = this.CurrentStreamProviderRuntime?.GetInvokeInterceptor(); #pragma warning restore 618 var requestInvoker = new GrainMethodInvoker(target, request, invoker, siloInterceptors, interfaceToImplementationMapping, invokeInterceptor); await requestInvoker.Invoke(); resultObject = requestInvoker.Result; } catch (Exception exc1) { if (invokeExceptionLogger.IsVerbose || message.Direction == Message.Directions.OneWay) { invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message, exc1); } if (exc1 is InconsistentStateException && target is Grain) { var activation = ((Grain)target).Data; invokeExceptionLogger.Info($"Deactivating {activation} due to inconsistent state."); this.DeactivateOnIdle(activation.ActivationId); } if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc1); } return; } if (message.Direction == Message.Directions.OneWay) { return; } SafeSendResponse(message, resultObject); } catch (Exception exc2) { logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc2); } } }
internal async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Invoke); return; } //MessagingProcessingStatisticsGroup.OnRequestProcessed(message, "Invoked"); if (Message.WriteMessagingTraces) { message.AddTimestamp(Message.LifecycleTag.InvokeIncoming); } RequestContext.Import(message.RequestContextData); if (Config.Globals.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContext.ExportToMessage(message); } var invoker = invokable.GetInvoker(message.InterfaceId, message.GenericGrainType); object resultObject; try { var request = (InvokeMethodRequest)message.BodyObject; if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = new StackTrace().ToString(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } resultObject = await invoker.Invoke(target, request.InterfaceId, request.MethodId, request.Arguments); } catch (Exception exc1) { if (invokeExceptionLogger.IsVerbose || message.Direction == Message.Directions.OneWay) { invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message, exc1); } if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc1); } return; } if (message.Direction == Message.Directions.OneWay) { return; } SafeSendResponse(message, resultObject); } catch (Exception exc2) { logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc2); } } }
public async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Invoke); return; } RequestContextExtensions.Import(message.RequestContextData); if (schedulingOptions.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message.TargetGrain, message.TargetActivation, message.DebugContext)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContextExtensions.ExportToMessage(message); } bool startNewTransaction = false; ITransactionInfo transactionInfo = message.TransactionInfo; if (message.IsTransactionRequired && transactionInfo == null) { // TODO: this should be a configurable parameter var transactionTimeout = Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(10); // Start a new transaction transactionInfo = await this.transactionAgent.Value.StartTransaction(message.IsReadOnly, transactionTimeout); startNewTransaction = true; } if (transactionInfo != null) { TransactionContext.SetTransactionInfo(transactionInfo); } object resultObject; try { var request = (InvokeMethodRequest)message.GetDeserializedBody(this.serializationManager); if (request.Arguments != null) { CancellationSourcesExtension.RegisterCancellationTokens(target, request, this.loggerFactory, logger, this, this.cancellationTokenRuntime); } var invoker = invokable.GetInvoker(typeManager, request.InterfaceId, message.GenericGrainType); if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = Utils.GetStackTrace(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } var requestInvoker = new GrainMethodInvoker(target, request, invoker, GrainCallFilters, interfaceToImplementationMapping); await requestInvoker.Invoke(); resultObject = requestInvoker.Result; } catch (Exception exc1) { if (invokeExceptionLogger.IsEnabled(LogLevel.Debug) || message.Direction == Message.Directions.OneWay) { invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message, exc1); } transactionInfo = TransactionContext.GetTransactionInfo(); if (transactionInfo != null) { // Must abort the transaction on exceptions transactionInfo.IsAborted = true; if (startNewTransaction) { var abortException = (exc1 as OrleansTransactionAbortedException) ?? new OrleansTransactionAbortedException(transactionInfo.TransactionId.ToString(), exc1); this.transactionAgent.Value.Abort(transactionInfo, abortException); exc1 = abortException; } } // If a grain allowed an inconsistent state exception to escape and the exception originated from // this activation, then deactivate it. var ise = exc1 as InconsistentStateException; if (ise != null && ise.IsSourceActivation) { // Mark the exception so that it doesn't deactivate any other activations. ise.IsSourceActivation = false; var activation = (target as Grain)?.Data; if (activation != null) { invokeExceptionLogger.Info($"Deactivating {activation} due to inconsistent state."); this.DeactivateOnIdle(activation.ActivationId); } } if (message.Direction != Message.Directions.OneWay) { TransactionContext.Clear(); SafeSendExceptionResponse(message, exc1); } return; } transactionInfo = TransactionContext.GetTransactionInfo(); if (transactionInfo != null && !transactionInfo.ReconcilePending(out var numberOrphans)) { var abortException = new OrleansOrphanCallException(transactionInfo.TransactionId.ToString(), numberOrphans); // Can't exit before the transaction completes. TransactionContext.GetTransactionInfo().IsAborted = true; if (startNewTransaction) { this.transactionAgent.Value.Abort(TransactionContext.GetTransactionInfo(), abortException); } if (message.Direction != Message.Directions.OneWay) { TransactionContext.Clear(); SafeSendExceptionResponse(message, abortException); } return; } if (startNewTransaction) { // This request started the transaction, so we try to commit before returning. await this.transactionAgent.Value.Commit(transactionInfo); TransactionContext.Clear(); } if (message.Direction == Message.Directions.OneWay) { return; } SafeSendResponse(message, resultObject); } catch (Exception exc2) { logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); try { if (exc2 is OrleansTransactionInDoubtException) { this.logger.LogError(exc2, "Transaction failed due to in doubt transaction"); } else if (TransactionContext.GetTransactionInfo() != null) { // Must abort the transaction on exceptions TransactionContext.GetTransactionInfo().IsAborted = true; var abortException = (exc2 as OrleansTransactionAbortedException) ?? new OrleansTransactionAbortedException(TransactionContext.GetTransactionInfo().TransactionId.ToString(), exc2); this.transactionAgent.Value.Abort(TransactionContext.GetTransactionInfo(), abortException); } } finally { TransactionContext.Clear(); if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc2); } } } finally { TransactionContext.Clear(); } }
internal async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Invoke); return; } RequestContext.Import(message.RequestContextData); if (Config.Globals.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContext.ExportToMessage(message); } object resultObject; try { var request = (InvokeMethodRequest) message.BodyObject; var invoker = invokable.GetInvoker(request.InterfaceId, message.GenericGrainType); if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = new StackTrace().ToString(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } // If the target has a grain-level interceptor or there is a silo-level interceptor, intercept the call. var shouldCallSiloWideInterceptor = SiloProviderRuntime.Instance.GetInvokeInterceptor() != null && target is IGrain; var intercepted = target as IGrainInvokeInterceptor; if (intercepted != null || shouldCallSiloWideInterceptor) { // Fetch the method info for the intercepted call. var implementationInvoker = invocationMethodInfoMap.GetInterceptedMethodInvoker(target.GetType(), request.InterfaceId, invoker); var methodInfo = implementationInvoker.GetMethodInfo(request.MethodId); if (shouldCallSiloWideInterceptor) { // There is a silo-level interceptor and possibly a grain-level interceptor. var runtime = SiloProviderRuntime.Instance; resultObject = await runtime.CallInvokeInterceptor(methodInfo, request, target, implementationInvoker); } else { // The grain has an interceptor, but there is no silo-wide interceptor. resultObject = await intercepted.Invoke(methodInfo, request, invoker); } } else { // The call is not intercepted. resultObject = await invoker.Invoke(target, request); } } catch (Exception exc1) { if (invokeExceptionLogger.IsVerbose || message.Direction == Message.Directions.OneWay) { invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message, exc1); } if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc1); } return; } if (message.Direction == Message.Directions.OneWay) return; SafeSendResponse(message, resultObject); } catch (Exception exc2) { logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); if (message.Direction != Message.Directions.OneWay) SafeSendExceptionResponse(message, exc2); } }
public async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { this.messagingTrace.OnDropExpiredMessage(message, MessagingStatisticsGroup.Phase.Invoke); return; } RequestContextExtensions.Import(message.RequestContextData); if (schedulingOptions.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget()) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message.TargetGrain, message.TargetActivation)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContextExtensions.ExportToMessage(message); } bool startNewTransaction = false; ITransactionInfo transactionInfo = message.TransactionInfo; if (message.IsTransactionRequired && transactionInfo == null) { // TODO: this should be a configurable parameter var transactionTimeout = Debugger.IsAttached ? TimeSpan.FromMinutes(30) : TimeSpan.FromSeconds(10); // Start a new transaction transactionInfo = await this.transactionAgent.StartTransaction(message.IsReadOnly, transactionTimeout); startNewTransaction = true; } if (transactionInfo != null) { TransactionContext.SetTransactionInfo(transactionInfo); } object resultObject; try { var request = (InvokeMethodRequest)message.BodyObject; if (request.Arguments != null) { CancellationSourcesExtension.RegisterCancellationTokens(target, request, this.loggerFactory, logger, this, this.cancellationTokenRuntime); } var invoker = invokable.GetInvoker(typeManager, request.InterfaceId, message.GenericGrainType); if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension) && !TryInstallExtension(request.InterfaceId, invokable, message.GenericGrainType, ref invoker)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = Utils.GetStackTrace(); #endif this.logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } messagingTrace.OnInvokeMessage(message); var requestInvoker = new GrainMethodInvoker(target, request, invoker, GrainCallFilters, interfaceToImplementationMapping); await requestInvoker.Invoke(); resultObject = requestInvoker.Result; } catch (Exception exc1) { if (message.Direction == Message.Directions.OneWay) { this.invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message + ": " + LogFormatter.PrintException(exc1), exc1); } else if (invokeExceptionLogger.IsEnabled(LogLevel.Debug)) { this.invokeExceptionLogger.Debug(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message + ": " + LogFormatter.PrintException(exc1), exc1); } if (transactionInfo != null) { transactionInfo.ReconcilePending(); // Record reason for abort, if not alread set transactionInfo.RecordException(exc1, serializationManager); if (startNewTransaction) { exc1 = transactionInfo.MustAbort(serializationManager); await this.transactionAgent.Abort(transactionInfo); TransactionContext.Clear(); } } // If a grain allowed an inconsistent state exception to escape and the exception originated from // this activation, then deactivate it. var ise = exc1 as InconsistentStateException; if (ise != null && ise.IsSourceActivation) { // Mark the exception so that it doesn't deactivate any other activations. ise.IsSourceActivation = false; var activation = (target as Grain)?.Data; if (activation != null) { this.invokeExceptionLogger.Info($"Deactivating {activation} due to inconsistent state."); this.DeactivateOnIdle(activation.ActivationId); } } if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc1); } return; } OrleansTransactionException transactionException = null; if (transactionInfo != null) { try { transactionInfo.ReconcilePending(); transactionException = transactionInfo.MustAbort(serializationManager); // This request started the transaction, so we try to commit before returning, // or if it must abort, tell participants that it aborted if (startNewTransaction) { try { if (transactionException == null) { var status = await this.transactionAgent.Resolve(transactionInfo); if (status != TransactionalStatus.Ok) { transactionException = status.ConvertToUserException(transactionInfo.Id); } } else { await this.transactionAgent.Abort(transactionInfo); } } finally { TransactionContext.Clear(); } } } catch (Exception e) { // we should never hit this, but if we do, the following message will help us diagnose this.logger.LogError(e, "Error in transaction post-grain-method-invocation code"); throw; } } if (message.Direction != Message.Directions.OneWay) { if (transactionException != null) { SafeSendExceptionResponse(message, transactionException); } else { SafeSendResponse(message, resultObject); } } return; } catch (Exception exc2) { this.logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); TransactionContext.Clear(); if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc2); } } finally { RequestContext.Clear(); } }
internal async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Invoke); return; } //MessagingProcessingStatisticsGroup.OnRequestProcessed(message, "Invoked"); if (Message.WriteMessagingTraces) message.AddTimestamp(Message.LifecycleTag.InvokeIncoming); RequestContext.ImportFromMessage(message); if (Config.Globals.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContext.ExportToMessage(message); } var invoker = invokable.GetInvoker(message.InterfaceId, message.GenericGrainType); object resultObject; try { var request = (InvokeMethodRequest) message.BodyObject; if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = new StackTrace().ToString(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } resultObject = await invoker.Invoke(target, request.InterfaceId, request.MethodId, request.Arguments); } catch (Exception exc1) { if (invokeExceptionLogger.IsVerbose || message.Direction == Message.Directions.OneWay) { invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message, exc1); } if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc1); } return; } if (message.Direction == Message.Directions.OneWay) return; SafeSendResponse(message, resultObject); } catch (Exception exc2) { logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); if (message.Direction != Message.Directions.OneWay) SafeSendExceptionResponse(message, exc2); } }
internal async Task Invoke(IAddressable target, IInvokable invokable, Message message) { try { // Don't process messages that have already timed out if (message.IsExpired) { message.DropExpiredMessage(MessagingStatisticsGroup.Phase.Invoke); return; } RequestContext.Import(message.RequestContextData); if (Config.Globals.PerformDeadlockDetection && !message.TargetGrain.IsSystemTarget) { UpdateDeadlockInfoInRequestContext(new RequestInvocationHistory(message)); // RequestContext is automatically saved in the msg upon send and propagated to the next hop // in RuntimeClient.CreateMessage -> RequestContext.ExportToMessage(message); } object resultObject; try { var request = (InvokeMethodRequest)message.BodyObject; var invoker = invokable.GetInvoker(request.InterfaceId, message.GenericGrainType); if (invoker is IGrainExtensionMethodInvoker && !(target is IGrainExtension)) { // We are trying the invoke a grain extension method on a grain // -- most likely reason is that the dynamic extension is not installed for this grain // So throw a specific exception here rather than a general InvalidCastException var error = String.Format( "Extension not installed on grain {0} attempting to invoke type {1} from invokable {2}", target.GetType().FullName, invoker.GetType().FullName, invokable.GetType().FullName); var exc = new GrainExtensionNotInstalledException(error); string extraDebugInfo = null; #if DEBUG extraDebugInfo = new StackTrace().ToString(); #endif logger.Warn(ErrorCode.Stream_ExtensionNotInstalled, string.Format("{0} for message {1} {2}", error, message, extraDebugInfo), exc); throw exc; } // If the target has a grain-level interceptor or there is a silo-level interceptor, intercept the call. var shouldCallSiloWideInterceptor = SiloProviderRuntime.Instance.GetInvokeInterceptor() != null && target is IGrain; var intercepted = target as IGrainInvokeInterceptor; if (intercepted != null || shouldCallSiloWideInterceptor) { // Fetch the method info for the intercepted call. var implementationInvoker = invocationMethodInfoMap.GetInterceptedMethodInvoker(target.GetType(), request.InterfaceId, invoker); var methodInfo = implementationInvoker.GetMethodInfo(request.MethodId); if (shouldCallSiloWideInterceptor) { // There is a silo-level interceptor and possibly a grain-level interceptor. var runtime = SiloProviderRuntime.Instance; resultObject = await runtime.CallInvokeInterceptor(methodInfo, request, target, implementationInvoker); } else { // The grain has an interceptor, but there is no silo-wide interceptor. resultObject = await intercepted.Invoke(methodInfo, request, invoker); } } else { // The call is not intercepted. // TODO: this await here is just grabbing the first exception of the AggregateException. As a framework we shouldn't do that. resultObject = await invoker.Invoke(target, request); } } catch (Exception exc1) { if (invokeExceptionLogger.IsVerbose || message.Direction == Message.Directions.OneWay) { invokeExceptionLogger.Warn(ErrorCode.GrainInvokeException, "Exception during Grain method call of message: " + message, exc1); } if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc1); } return; } if (message.Direction == Message.Directions.OneWay) { return; } SafeSendResponse(message, resultObject); } catch (Exception exc2) { logger.Warn(ErrorCode.Runtime_Error_100329, "Exception during Invoke of message: " + message, exc2); if (message.Direction != Message.Directions.OneWay) { SafeSendExceptionResponse(message, exc2); } } }