예제 #1
0
        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);
            }
        }
예제 #2
0
        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));
        }
예제 #3
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);
                }
            }
        }
예제 #4
0
        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));
            }
        }
예제 #5
0
        // 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");
                }
            }
        }