private async Task Deliver <TBusCommand>(TBusCommand busCommand, Type commandType, NimbusMessage nimbusMessage) where TBusCommand : IBusCommand { var queuePath = _router.Route(commandType, QueueOrTopic.Queue); nimbusMessage.DestinedForQueue(queuePath); var sw = Stopwatch.StartNew(); using (var scope = _dependencyResolver.CreateChildScope()) { Exception exception; var interceptors = _outboundInterceptorFactory.CreateInterceptors(scope, nimbusMessage); try { _logger.LogDispatchAction("Sending", queuePath, sw.Elapsed); var sender = _transport.GetQueueSender(queuePath); foreach (var interceptor in interceptors) { await interceptor.OnCommandSending(busCommand, nimbusMessage); } await sender.Send(nimbusMessage); foreach (var interceptor in interceptors.Reverse()) { await interceptor.OnCommandSent(busCommand, nimbusMessage); } _logger.LogDispatchAction("Sent", queuePath, sw.Elapsed); return; } catch (Exception exc) { exception = exc; } foreach (var interceptor in interceptors.Reverse()) { await interceptor.OnCommandSendingError(busCommand, nimbusMessage, exception); } _logger.LogDispatchError("sending", queuePath, sw.Elapsed, exception); } }
public Task DeliverAfter(NimbusMessage message, DateTimeOffset deliveryTime) { _logger.Debug("Enqueuing {MessageId} for re-delivery at {DeliverAt}", message.MessageId, deliveryTime); // Deliberately not awaiting this task. We want it to run in the background. Task.Run(async() => { var delay = deliveryTime.Subtract(_clock.UtcNow); if (delay < TimeSpan.Zero) { delay = TimeSpan.Zero; } await Task.Delay(delay); _logger.Debug("Re-delivering {MessageId} (attempt {Attempt})", message.MessageId, message.DeliveryAttempts.Length); var sender = _transport.GetQueueSender(message.DeliverTo); await sender.Send(message); }).ConfigureAwaitFalse(); return(Task.Delay(0)); }
// ReSharper disable UnusedMember.Local private async Task Dispatch <TBusRequest, TBusResponse>(TBusRequest busRequest, NimbusMessage nimbusMessage, Type handlerType) where TBusRequest : IBusMulticastRequest <TBusRequest, TBusResponse> where TBusResponse : IBusMulticastResponse { var replyQueueName = nimbusMessage.From; var replyQueueClient = _transport.GetQueueSender(replyQueueName); Exception exception = null; using (var scope = _dependencyResolver.CreateChildScope()) { var handler = (IHandleMulticastRequest <TBusRequest, TBusResponse>)scope.Resolve(handlerType); _propertyInjector.Inject(handler, nimbusMessage); var inboundInterceptors = _inboundInterceptorFactory.CreateInterceptors(scope, handler, busRequest, nimbusMessage); foreach (var interceptor in inboundInterceptors) { _logger.Debug("Executing OnRequestHandlerExecuting on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]", interceptor.GetType().FullName, nimbusMessage.SafelyGetBodyTypeNameOrDefault(), nimbusMessage.MessageId, nimbusMessage.CorrelationId); await interceptor.OnMulticastRequestHandlerExecuting(busRequest, nimbusMessage); _logger.Debug("Executed OnRequestHandlerExecuting on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]", interceptor.GetType().FullName, nimbusMessage.SafelyGetBodyTypeNameOrDefault(), nimbusMessage.MessageId, nimbusMessage.CorrelationId); } try { var response = await handler.Handle(busRequest); if (response != null) { var responseMessage = await _nimbusMessageFactory.CreateSuccessfulResponse(replyQueueName, response, nimbusMessage); DispatchLoggingContext.NimbusMessage = responseMessage; var outboundInterceptors = _outboundInterceptorFactory.CreateInterceptors(scope, nimbusMessage); _logger.Debug("Sending successful response message {0} to {1} [MessageId:{2}, CorrelationId:{3}]", responseMessage.SafelyGetBodyTypeNameOrDefault(), replyQueueName, nimbusMessage.MessageId, nimbusMessage.CorrelationId); foreach (var interceptor in outboundInterceptors) { await interceptor.OnMulticastResponseSending(response, nimbusMessage); } await replyQueueClient.Send(responseMessage); foreach (var interceptor in outboundInterceptors.Reverse()) { await interceptor.OnMulticastResponseSent(response, nimbusMessage); } _logger.Debug("Sent successful response message {0} to {1} [MessageId:{2}, CorrelationId:{3}]", nimbusMessage.SafelyGetBodyTypeNameOrDefault(), replyQueueName, nimbusMessage.MessageId, nimbusMessage.CorrelationId); } else { _logger.Debug("Handler declined to reply. [MessageId: {0}, CorrelationId: {1}]", nimbusMessage.MessageId, nimbusMessage.CorrelationId); } } catch (Exception exc) { // Capture any exception so we can send a failed response outside the catch block exception = exc; } if (exception == null) { foreach (var interceptor in inboundInterceptors.Reverse()) { _logger.Debug("Executing OnRequestHandlerSuccess on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]", interceptor.GetType().FullName, nimbusMessage.SafelyGetBodyTypeNameOrDefault(), nimbusMessage.MessageId, nimbusMessage.CorrelationId); await interceptor.OnMulticastRequestHandlerSuccess(busRequest, nimbusMessage); _logger.Debug("Executed OnRequestHandlerSuccess on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]", interceptor.GetType().FullName, nimbusMessage.SafelyGetBodyTypeNameOrDefault(), nimbusMessage.MessageId, nimbusMessage.CorrelationId); } } else { foreach (var interceptor in inboundInterceptors.Reverse()) { _logger.Debug("Executing OnRequestHandlerError on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]", interceptor.GetType().FullName, nimbusMessage.SafelyGetBodyTypeNameOrDefault(), nimbusMessage.MessageId, nimbusMessage.CorrelationId); await interceptor.OnMulticastRequestHandlerError(busRequest, nimbusMessage, exception); _logger.Debug("Executed OnRequestHandlerError on {0} for message [MessageType:{1}, MessageId:{2}, CorrelationId:{3}]", interceptor.GetType().FullName, nimbusMessage.SafelyGetBodyTypeNameOrDefault(), nimbusMessage.MessageId, nimbusMessage.CorrelationId); } var failedResponseMessage = await _nimbusMessageFactory.CreateFailedResponse(replyQueueName, nimbusMessage, exception); _logger.Warn("Sending failed response message to {0} [MessageId:{1}, CorrelationId:{2}]", replyQueueName, exception.Message, nimbusMessage.MessageId, nimbusMessage.CorrelationId); await replyQueueClient.Send(failedResponseMessage); _logger.Debug("Sent failed response message to {0} [MessageId:{1}, CorrelationId:{2}]", replyQueueName, nimbusMessage.MessageId, nimbusMessage.CorrelationId); } } }
public async Task <TResponse> SendRequest <TRequest, TResponse>(IBusRequest <TRequest, TResponse> busRequest, TimeSpan timeout) where TRequest : IBusRequest <TRequest, TResponse> where TResponse : IBusResponse { var requestType = busRequest.GetType(); _knownMessageTypeVerifier.AssertValidMessageType(requestType); var queuePath = _router.Route(requestType, QueueOrTopic.Queue); var nimbusMessage = (await _nimbusMessageFactory.Create(queuePath, busRequest)) .WithRequestTimeout(timeout) ; DispatchLoggingContext.NimbusMessage = nimbusMessage; var expiresAfter = _clock.UtcNow.Add(timeout); var responseCorrelationWrapper = _requestResponseCorrelator.RecordRequest <TResponse>(nimbusMessage.MessageId, expiresAfter); var sw = Stopwatch.StartNew(); using (var scope = _dependencyResolver.CreateChildScope()) { Exception exception; var interceptors = _outboundInterceptorFactory.CreateInterceptors(scope, nimbusMessage); try { _logger.LogDispatchAction("Sending", queuePath, sw.Elapsed); var sender = _transport.GetQueueSender(queuePath); foreach (var interceptor in interceptors) { await interceptor.OnRequestSending(busRequest, nimbusMessage); } await sender.Send(nimbusMessage); foreach (var interceptor in interceptors.Reverse()) { await interceptor.OnRequestSent(busRequest, nimbusMessage); } _logger.LogDispatchAction("Sent", queuePath, sw.Elapsed); _logger.LogDispatchAction("Waiting for response to", queuePath, sw.Elapsed); var response = await responseCorrelationWrapper.WaitForResponse(timeout); _logger.LogDispatchAction("Received response to", queuePath, sw.Elapsed); return(response); } catch (Exception exc) { exception = exc; } foreach (var interceptor in interceptors.Reverse()) { await interceptor.OnRequestSendingError(busRequest, nimbusMessage, exception); } _logger.LogDispatchError("sending", queuePath, sw.Elapsed, exception); //FIXME "sending" here is a bit misleading. The message could have been sent and the response not received. ExceptionDispatchInfo.Capture(exception).Throw(); return(default(TResponse)); } }
// ReSharper disable UnusedMember.Local private async Task Dispatch <TBusRequest, TBusResponse>(TBusRequest busRequest, NimbusMessage nimbusMessage, Type handlerType) where TBusRequest : IBusRequest <TBusRequest, TBusResponse> where TBusResponse : IBusResponse { var replyQueueName = nimbusMessage.From; var replyQueueClient = _transport.GetQueueSender(replyQueueName); using (var scope = _dependencyResolver.CreateChildScope()) { var handler = (IHandleRequest <TBusRequest, TBusResponse>)scope.Resolve(handlerType); _propertyInjector.Inject(handler, nimbusMessage); var inboundInterceptors = _inboundInterceptorFactory.CreateInterceptors(scope, handler, busRequest, nimbusMessage); Exception exception = null; try { foreach (var interceptor in inboundInterceptors) { _logger.Debug("Executing OnRequestHandlerExecuting for {InterceptorType}", interceptor.GetType().Name); await interceptor.OnRequestHandlerExecuting(busRequest, nimbusMessage); _logger.Debug("Executed OnRequestHandlerExecuting for {InterceptorType}", interceptor.GetType().Name); } _logger.Debug("Dispatching to {HandlerType}", handler.GetType().Name); var handlerTask = handler.Handle(busRequest); var response = await handlerTask; _logger.Debug("Dispatched to {HandlerType}", handler.GetType().Name); var responseMessage = await _nimbusMessageFactory.CreateSuccessfulResponse(replyQueueName, response, nimbusMessage); DispatchLoggingContext.NimbusMessage = responseMessage; var outboundInterceptors = _outboundInterceptorFactory.CreateInterceptors(scope, nimbusMessage); foreach (var interceptor in outboundInterceptors.Reverse()) { _logger.Debug("Executing OnResponseSending for {InterceptorType}", interceptor.GetType().Name); await interceptor.OnResponseSending(response, responseMessage); _logger.Debug("Executed OnResponseSending for {InterceptorType}", interceptor.GetType().Name); } _logger.Debug("Sending successful response message"); await replyQueueClient.Send(responseMessage); _logger.Debug("Sent successful response message"); foreach (var interceptor in outboundInterceptors.Reverse()) { _logger.Debug("Executing OnResponseSent for {InterceptorType}", interceptor.GetType().Name); await interceptor.OnResponseSent(response, responseMessage); _logger.Debug("Executed OnResponseSent for {InterceptorType}", interceptor.GetType().Name); } } catch (Exception exc) { // Capture any exception so we can send a failed response outside the catch block exception = exc; _logger.Warn(exc, "Request message dispatch failed."); } if (exception == null) { foreach (var interceptor in inboundInterceptors.Reverse()) { _logger.Debug("Executing OnRequestHandlerSuccess for {InterceptorType}", interceptor.GetType().Name); await interceptor.OnRequestHandlerSuccess(busRequest, nimbusMessage); _logger.Debug("Executed OnRequestHandlerSuccess for {InterceptorType}", interceptor.GetType().Name); } } else { foreach (var interceptor in inboundInterceptors.Reverse()) { _logger.Debug("Executing OnRequestHandlerError for {InterceptorType}", interceptor.GetType().Name); await interceptor.OnRequestHandlerError(busRequest, nimbusMessage, exception); _logger.Debug("Executed OnRequestHandlerError for {InterceptorType}", interceptor.GetType().Name); } var failedResponseMessage = (await _nimbusMessageFactory.CreateFailedResponse(replyQueueName, nimbusMessage, exception)); _logger.Debug("Sending failed response message"); await replyQueueClient.Send(failedResponseMessage); _logger.Debug("Sent failed response message"); } } }