示例#1
0
        public DateTimeOffset CalculateNextRetryTime(NimbusMessage message)
        {
            var attemptCount  = message.DeliveryAttempts.Length;
            var secondsToWait = Math.Pow(2, attemptCount + 1);

            return(DateTimeOffset.Now.AddSeconds(secondsToWait));
        }
        public void TheyShouldBeResolvable()
        {
            var interceptorTypes = new[] {typeof (DummyInterceptor)};

            var builder = new ContainerBuilder();
            var typeProvider = Substitute.For<ITypeProvider>();
            typeProvider.InterceptorTypes.Returns(interceptorTypes);

            builder.RegisterNimbus(typeProvider);

            using (var container = builder.Build())
            using (var dependencyResolver = container.Resolve<IDependencyResolver>())
            using (var scope = dependencyResolver.CreateChildScope())
            {
                var interceptorSetting = new GlobalOutboundInterceptorTypesSetting
                                         {
                                             Value = interceptorTypes
                                         };
                var outboundInterceptorFactory = new OutboundInterceptorFactory(interceptorSetting,
                                                                                new PropertyInjector(Substitute.For<IClock>(),
                                                                                                     Substitute.For<IDispatchContextManager>(),
                                                                                                     Substitute.For<ILargeMessageBodyStore>()));

                var dummyNimbusMessage = new NimbusMessage("nullQueue");
                var interceptors = outboundInterceptorFactory.CreateInterceptors(scope, dummyNimbusMessage);

                interceptors.Count().ShouldBe(1);
            }
        }
        public async Task Dispatch(NimbusMessage message)
        {
            if (!message.InReplyToMessageId.HasValue)
            {
                _logger.Error($"Received a reply message without an {nameof(NimbusMessage.InReplyToMessageId)} property.");
                return;
            }

            var requestId = (Guid) message.InReplyToMessageId;

            var responseCorrelationWrapper = _requestResponseCorrelator.TryGetWrapper(requestId);
            if (responseCorrelationWrapper == null)
            {
                _logger.Warn("Received a reply to request {RequestMessageId} that had no corresponding request waiting for it.", requestId);
                return;
            }

            var success = message.Properties[MessagePropertyKeys.RequestSuccessful] as bool? ?? false;
            if (success)
            {
                _logger.Debug("Received successful response");

                var response = message.Payload;
                await responseCorrelationWrapper.Reply(response);
            }
            else
            {
                _logger.Debug("Received failure response");

                var exceptionMessage = (string) message.Properties[MessagePropertyKeys.ExceptionMessage];
                var exceptionStackTrace = (string) message.Properties[MessagePropertyKeys.ExceptionStackTrace];
                await responseCorrelationWrapper.Throw(exceptionMessage, exceptionStackTrace);
            }
        }
示例#4
0
        public async Task DeliverAfter(NimbusMessage message, DateTimeOffset deliveryTime)
        {
            if (await _queueManager.QueueExists(message.DeliverTo))
            {
                message.DeliverAfter = deliveryTime;
                var messageSender = await _queueManager.CreateMessageSender(message.DeliverTo);

                var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);

                await messageSender.SendAsync(brokeredMessage);

                return;
            }

            if (await _queueManager.TopicExists(message.DeliverTo))
            {
                message.DeliverAfter = deliveryTime;
                var topicSender = await _queueManager.CreateTopicSender(message.DeliverTo);

                var brokeredMessage2 = await _brokeredMessageFactory.BuildBrokeredMessage(message);

                await topicSender.SendAsync(brokeredMessage2);

                return;
            }

            throw new NotSupportedException("Message redelivery was requested but neither a queue path nor a topic path could be found.");
        }
        private async Task <BrokeredMessage> When(BrokeredMessageFactory brokeredMessageFactory)
        {
            var bigFatObject  = new string(Enumerable.Range(0, 256 * 1024).Select(i => '.').ToArray());
            var nimbusMessage = new NimbusMessage("noPath", bigFatObject);

            return(await brokeredMessageFactory.BuildBrokeredMessage(nimbusMessage));
        }
        public async Task Send(NimbusMessage message)
        {
            await _retry.DoAsync(async () =>
                                       {
                                           var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);

                                           var topicClient = GetTopicClient();
                                           try
                                           {
                                               await topicClient.SendAsync(brokeredMessage);
                                           }
                                           catch (MessagingEntityNotFoundException exc)
                                           {
                                               _logger.Error(exc, "The referenced topic path {TopicPath} no longer exists", _topicPath);
                                               await _queueManager.MarkTopicAsNonExistent(_topicPath);
                                               DiscardTopicClient();
                                               throw;
                                           }
                                           catch (Exception)
                                           {
                                               DiscardTopicClient();
                                               throw;
                                           }
                                       },
                                 "Sending message to topic").ConfigureAwaitFalse();
        }
        private AuditEvent CreateAuditEvent(object message, NimbusMessage nimbusMessage)
        {
            var timestamp  = UtcNow();
            var auditEvent = new AuditEvent(message.GetType().FullName, message, nimbusMessage.ExtractProperties(), timestamp);

            return(auditEvent);
        }
        public async Task Send(NimbusMessage message)
        {
            await _retry.DoAsync(async () =>
                                       {
                                           var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);

                                           var messageSender = GetMessageSender();
                                           try
                                           {
                                               await messageSender.SendAsync(brokeredMessage);
                                           }
                                           catch (MessagingEntityNotFoundException exc)
                                           {
                                               _logger.Error(exc, "The referenced queue {QueuePath} no longer exists", _queuePath);
                                               await _queueManager.MarkQueueAsNonExistent(_queuePath);
                                               DiscardMessageSender();
                                               throw;
                                           }
                                           catch (Exception)
                                           {
                                               DiscardMessageSender();
                                               throw;
                                           }
                                       },
                                 "Sending message to queue").ConfigureAwaitFalse();
        }
示例#9
0
 public virtual async Task OnRequestSendingError <TBusRequest, TBusResponse>(IBusRequest <TBusRequest, TBusResponse> busRequest,
                                                                             NimbusMessage nimbusMessage,
                                                                             Exception exception)
     where TBusRequest : IBusRequest <TBusRequest, TBusResponse>
     where TBusResponse : IBusResponse
 {
 }
示例#10
0
        public override Task OnEventHandlerExecuting <TBusEvent>(TBusEvent busEvent, NimbusMessage nimbusMessage)
        {
            CallContext.LogicalSetData(nameof(DispatchContext.CorrelationId), DispatchContext.CorrelationId);
            CallContext.LogicalSetData(nameof(DispatchContext.ResultOfMessageId), DispatchContext.ResultOfMessageId);

            return(base.OnEventHandlerExecuting(busEvent, nimbusMessage));
        }
        public void TheyShouldBeResolvable()
        {
            var interceptorTypes = new[] { typeof(DummyInterceptor) };

            var builder      = new ContainerBuilder();
            var typeProvider = Substitute.For <ITypeProvider>();

            typeProvider.InterceptorTypes.Returns(interceptorTypes);

            builder.RegisterNimbus(typeProvider);

            using (var container = builder.Build())
                using (var dependencyResolver = container.Resolve <IDependencyResolver>())
                    using (var scope = dependencyResolver.CreateChildScope())
                    {
                        var interceptorSetting = new GlobalOutboundInterceptorTypesSetting
                        {
                            Value = interceptorTypes
                        };
                        var outboundInterceptorFactory = new OutboundInterceptorFactory(interceptorSetting,
                                                                                        new PropertyInjector(Substitute.For <IClock>(),
                                                                                                             Substitute.For <IDispatchContextManager>(),
                                                                                                             Substitute.For <ILargeMessageBodyStore>()));

                        var dummyNimbusMessage = new NimbusMessage("nullQueue");
                        var interceptors       = outboundInterceptorFactory.CreateInterceptors(scope, dummyNimbusMessage);

                        interceptors.Count().ShouldBe(1);
                    }
        }
示例#12
0
        internal static TimeSpan GetRequestTimeout(this NimbusMessage message)
        {
            var requestTimeoutInMilliseconds = (int)message.Properties[MessagePropertyKeys.RequestTimeoutInMilliseconds];
            var timeout = TimeSpan.FromMilliseconds(requestTimeoutInMilliseconds);

            return(timeout);
        }
示例#13
0
 public async Task DeliverAfter(NimbusMessage message, DateTimeOffset deliveryTime)
 {
     message.DeliverAfter = deliveryTime;
     var messageSender = await _queueManager.CreateMessageSender(message.DeliverTo);
     var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);
     await messageSender.SendAsync(brokeredMessage);
 }
示例#14
0
        public async Task Send(NimbusMessage message)
        {
            await _retry.DoAsync(async() =>
            {
                var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);

                var topicClient = GetTopicClient();
                try
                {
                    await topicClient.SendAsync(brokeredMessage);
                }
                catch (MessagingEntityNotFoundException exc)
                {
                    _logger.Error(exc, "The referenced topic path {TopicPath} no longer exists", _topicPath);
                    await _queueManager.MarkTopicAsNonExistent(_topicPath);
                    DiscardTopicClient();
                    throw;
                }
                catch (Exception)
                {
                    DiscardTopicClient();
                    throw;
                }
            },
                                 "Sending message to topic").ConfigureAwaitFalse();
        }
示例#15
0
        public async Task Send(NimbusMessage message)
        {
            await _retry.DoAsync(async() =>
            {
                var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);

                var messageSender = GetMessageSender();
                try
                {
                    await messageSender.SendAsync(brokeredMessage);
                }
                catch (MessagingEntityNotFoundException exc)
                {
                    _logger.Error(exc, "The referenced queue {QueuePath} no longer exists", _queuePath);
                    await _queueManager.MarkQueueAsNonExistent(_queuePath);
                    DiscardMessageSender();
                    throw;
                }
                catch (Exception)
                {
                    DiscardMessageSender();
                    throw;
                }
            },
                                 "Sending message to queue").ConfigureAwaitFalse();
        }
示例#16
0
        public async Task<NimbusMessage> CreateSuccessfulResponse(string destinationPath, object responsePayload, NimbusMessage originalRequest)
        {
            var responseMessage = (await Create(destinationPath, responsePayload))
                .WithReplyToRequestId(originalRequest.MessageId)
                .WithProperty(MessagePropertyKeys.RequestSuccessful, true);

            return responseMessage;
        }
        public async Task Post(NimbusMessage nimbusMessage)
        {
            var messageSender = await _queueManager.CreateDeadQueueMessageSender();

            var message = await _brokeredMessageFactory.BuildMessage(nimbusMessage);

            await messageSender.SendAsync(message);
        }
 public IOutboundInterceptor[] CreateInterceptors(IDependencyResolverScope scope, NimbusMessage nimbusMessage)
 {
     return _globalOutboundInterceptorTypes
         .Value
         .Select(t => (IOutboundInterceptor) scope.Resolve(t))
         .Do(interceptor => _propertyInjector.Inject(interceptor, nimbusMessage))
         .ToArray();
 }
示例#19
0
        public async Task DeliverAfter(NimbusMessage message, DateTimeOffset deliveryTime)
        {
            message.DeliverAfter = deliveryTime;
            var messageSender = await _queueManager.CreateMessageSender(message.DeliverTo);

            var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);

            await messageSender.SendAsync(brokeredMessage);
        }
示例#20
0
 public Task Post(NimbusMessage message)
 {
     return(Task.Run(() =>
     {
         var database = _databaseFunc();
         var serialized = _serializer.Serialize(message);
         database.ListRightPush(_deadLetterOfficeRedisKey, serialized);
     }).ConfigureAwaitFalse());
 }
            public void Inject(object handlerOrInterceptor, NimbusMessage nimbusMessage)
            {
                var requiresBusId = handlerOrInterceptor as IRequireBusId;

                if (requiresBusId != null)
                {
                    requiresBusId.BusId = _busId;
                }
            }
示例#22
0
 public Task Post(NimbusMessage message)
 {
     return Task.Run(() =>
                     {
                         var database = _databaseFunc();
                         var serialized = _serializer.Serialize(message);
                         database.ListRightPush(_deadLetterOfficeRedisKey, serialized);
                     }).ConfigureAwaitFalse();
 }
示例#23
0
        public async Task Dispatch(NimbusMessage message)
        {
            var busCommand  = message.Payload;
            var messageType = busCommand.GetType();

            // There should only ever be a single command handler
            var handlerType = _handlerMap.GetSingleHandlerTypeFor(messageType);

            await Dispatch((dynamic)busCommand, message, handlerType);
        }
        private static string DeriveMessageQueuePath(NimbusMessage message)
        {
            object subscriptionName;
            if (message.Properties.TryGetValue(MessagePropertyKeys.RedeliveryToSubscriptionName, out subscriptionName))
            {
                return InProcessTransport.FullyQualifiedSubscriptionPath(message.DeliverTo, (string) subscriptionName);
            }

            return message.DeliverTo;
        }
示例#25
0
        public async Task Dispatch(NimbusMessage message)
        {
            var busEvent    = message.Payload;
            var messageType = busEvent.GetType();

            // There should only ever be a single event handler associated with this dispatcher
            var handlerType = _handlerMap.GetSingleHandlerTypeFor(messageType);

            await(Task) Dispatch((dynamic)busEvent, message, handlerType);
        }
示例#26
0
        public async Task<NimbusMessage> CreateFailedResponse(string destinationPath, NimbusMessage originalRequest, Exception exception)
        {
            var responseMessage = (await Create(destinationPath, null))
                .WithReplyToRequestId(originalRequest.MessageId)
                .WithProperty(MessagePropertyKeys.RequestSuccessful, false);

            foreach (var prop in exception.ExceptionDetailsAsProperties(_clock.UtcNow)) responseMessage.Properties.Add(prop.Key, prop.Value);

            return responseMessage;
        }
示例#27
0
 public Task Send(NimbusMessage message)
 {
     return(Task.Run(() =>
     {
         var serialized = _serializer.Serialize(message);
         var database = _databaseFunc();
         database.ListRightPush(_redisKey, serialized);
         database.Publish(_redisKey, string.Empty);
     }).ConfigureAwaitFalse());
 }
示例#28
0
 public Task Send(NimbusMessage message)
 {
     return Task.Run(() =>
                     {
                         var serialized = _serializer.Serialize(message);
                         var database = _databaseFunc();
                         database.ListRightPush(_redisKey, serialized);
                         database.Publish(_redisKey, string.Empty);
                     }).ConfigureAwaitFalse();
 }
        private static string DeriveMessageQueuePath(NimbusMessage message)
        {
            object subscriptionName;

            if (message.Properties.TryGetValue(MessagePropertyKeys.RedeliveryToSubscriptionName, out subscriptionName))
            {
                return(InProcessTransport.FullyQualifiedSubscriptionPath(message.DeliverTo, (string)subscriptionName));
            }

            return(message.DeliverTo);
        }
示例#30
0
        public async Task Dispatch(NimbusMessage message)
        {
            var busRequest  = message.Payload;
            var messageType = busRequest.GetType();

            // There should only ever be a single multicast request handler associated with this dispatcher
            var handlerType    = _handlerMap.GetSingleHandlerTypeFor(messageType);
            var dispatchMethod = GetGenericDispatchMethodFor(busRequest);

            await(Task) dispatchMethod.Invoke(this, new[] { busRequest, message, handlerType });
        }
示例#31
0
 private async Task AddToCompetingSubscribersQueue(NimbusMessage message)
 {
     var clone = Clone(message);
     AsyncBlockingCollection<NimbusMessage> topicQueue;
     if (!_messageStore.TryGetExistingMessageQueue(_topic.TopicPath, out topicQueue))
     {
         _logger.Warn("A message was sent to an in-process topic {TopicPath} but nobody is listening on that topic. Not sending.", _topic.TopicPath);
         return;
     }
     await topicQueue.Add(clone);
 }
示例#32
0
        public override async Task OnEventPublished <TBusEvent>(TBusEvent busEvent, NimbusMessage nimbusMessage)
        {
            // Quis custodiet ipsos custodes? ;)
            if (busEvent is AuditEvent)
            {
                return;
            }

            var auditEvent = CreateAuditEvent(busEvent, nimbusMessage);
            await Bus.Publish(auditEvent);
        }
示例#33
0
 public async Task Send(NimbusMessage message)
 {
     var messageClone = (NimbusMessage) _serializer.Deserialize(_serializer.Serialize(message), typeof (NimbusMessage));
     AsyncBlockingCollection<NimbusMessage> messageQueue;
     if (!_messageStore.TryGetExistingMessageQueue(_queue.QueuePath, out messageQueue))
     {
         _logger.Warn("A message was sent to an in-process queue {QueuePath} but nobody is listening on that queue. Not sending.", _queue.QueuePath);
         return;
     }
     await messageQueue.Add(messageClone);
 }
示例#34
0
        public async Task Send(NimbusMessage message)
        {
            var messageClone = (NimbusMessage)_serializer.Deserialize(_serializer.Serialize(message), typeof(NimbusMessage));
            AsyncBlockingCollection <NimbusMessage> messageQueue;

            if (!_messageStore.TryGetExistingMessageQueue(_queue.QueuePath, out messageQueue))
            {
                _logger.Warn("A message was sent to an in-process queue {QueuePath} but nobody is listening on that queue. Not sending.", _queue.QueuePath);
                return;
            }
            await messageQueue.Add(messageClone);
        }
示例#35
0
        public override async Task OnEventPublishing <TBusEvent>(TBusEvent busEvent, NimbusMessage nimbusMessage)
        {
            // Quis custodiet ipsos custodes? ;)
            var auditEvent = busEvent as AuditEvent;

            if (auditEvent == null)
            {
                return;
            }

            nimbusMessage.Properties["AuditedMessageType"] = auditEvent.MessageType;
        }
示例#36
0
        private async Task AddToCompetingSubscribersQueue(NimbusMessage message)
        {
            var clone = Clone(message);
            AsyncBlockingCollection <NimbusMessage> topicQueue;

            if (!_messageStore.TryGetExistingMessageQueue(_topic.TopicPath, out topicQueue))
            {
                _logger.Warn("A message was sent to an in-process topic {TopicPath} but nobody is listening on that topic. Not sending.", _topic.TopicPath);
                return;
            }
            await topicQueue.Add(clone);
        }
示例#37
0
        public Task<NimbusMessage> Create(string destinationPath, [AllowNull] object payload)
        {
            var nimbusMessage = new NimbusMessage(destinationPath, payload);
            var expiresAfter = _clock.UtcNow.AddSafely(_timeToLive.Value);
            var currentDispatchContext = _dispatchContextManager.GetCurrentDispatchContext();
            nimbusMessage.PrecedingMessageId = currentDispatchContext.ResultOfMessageId;
            nimbusMessage.CorrelationId = currentDispatchContext.CorrelationId;
            nimbusMessage.From = _replyQueueName;
            nimbusMessage.ExpiresAfter = expiresAfter;

            return Task.FromResult(nimbusMessage);
        }
示例#38
0
        public void Inject(object handlerOrInterceptor, NimbusMessage nimbusMessage)
        {
            var requireBus = handlerOrInterceptor as IRequireBus;

            if (requireBus != null)
            {
                requireBus.Bus = Bus;
            }

            var requiresBusId = handlerOrInterceptor as IRequireBusId;

            if (requiresBusId != null)
            {
                requiresBusId.BusId = Bus.InstanceId;
            }

            var requireDispatchContext = handlerOrInterceptor as IRequireDispatchContext;

            if (requireDispatchContext != null)
            {
                requireDispatchContext.DispatchContext = _dispatchContextManager.GetCurrentDispatchContext();
            }

            var requireNimbusMessage = handlerOrInterceptor as IRequireNimbusMessage;

            if (requireNimbusMessage != null)
            {
                requireNimbusMessage.NimbusMessage = nimbusMessage;
            }

            var requireDateTime = handlerOrInterceptor as IRequireDateTime;

            if (requireDateTime != null)
            {
                requireDateTime.UtcNow = () => _clock.UtcNow;
            }

            var requireLargeMessageBodyStore = handlerOrInterceptor as IRequireLargeMessageBodyStore;

            if (requireLargeMessageBodyStore != null)
            {
                requireLargeMessageBodyStore.LargeMessageBodyStore = _largeMessageBodyStore;
            }

            var requireMessageProperties = handlerOrInterceptor as IRequireMessageProperties;

            if (requireMessageProperties != null)
            {
                var properties = nimbusMessage.ExtractProperties();
                requireMessageProperties.MessageProperties = properties;
            }
        }
示例#39
0
        public Task <NimbusMessage> Create(string destinationPath, [AllowNull] object payload)
        {
            var nimbusMessage          = new NimbusMessage(destinationPath, payload);
            var expiresAfter           = _clock.UtcNow.AddSafely(_timeToLive.Value);
            var currentDispatchContext = _dispatchContextManager.GetCurrentDispatchContext();

            nimbusMessage.PrecedingMessageId = currentDispatchContext.ResultOfMessageId;
            nimbusMessage.CorrelationId      = currentDispatchContext.CorrelationId;
            nimbusMessage.From         = _replyQueueName;
            nimbusMessage.ExpiresAfter = expiresAfter;

            return(Task.FromResult(nimbusMessage));
        }
示例#40
0
 private async Task AddToMulticastSubscriberQueues(NimbusMessage message)
 {
     await _topic.SubscriptionNames
     .Select(subscriptionName =>
     {
         var messageClone = Clone(message);
         var fullyQualifiedSubscriptionPath = InProcessTransport.FullyQualifiedSubscriptionPath(_topic.TopicPath, subscriptionName);
         //message.To = fullyQualifiedSubscriptionPath;  //FIXME find an elegant solution for this
         var subscriptionQueue = _messageStore.GetOrCreateMessageQueue(fullyQualifiedSubscriptionPath);
         var task = subscriptionQueue.Add(messageClone);
         return(task);
     })
     .WhenAll();
 }
示例#41
0
 private async Task AddToMulticastSubscriberQueues(NimbusMessage message)
 {
     await _topic.SubscriptionNames
                 .Select(subscriptionName =>
                         {
                             var messageClone = Clone(message);
                             var fullyQualifiedSubscriptionPath = InProcessTransport.FullyQualifiedSubscriptionPath(_topic.TopicPath, subscriptionName);
                             //message.To = fullyQualifiedSubscriptionPath;  //FIXME find an elegant solution for this
                             var subscriptionQueue = _messageStore.GetOrCreateMessageQueue(fullyQualifiedSubscriptionPath);
                             var task = subscriptionQueue.Add(messageClone);
                             return task;
                         })
                 .WhenAll();
 }
        public Task DeliverAfter(NimbusMessage message, DateTimeOffset 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);
                               AsyncBlockingCollection<NimbusMessage> queue;
                               if (!_messageStore.TryGetExistingMessageQueue(message.DeliverTo, out queue)) return;
                               await queue.Add(message);
                           }).ConfigureAwaitFalse();

            return Task.Delay(0);
        }
示例#43
0
        public Task<NimbusMessage> Create(string destinationPath, [AllowNull] object payload)
        {
            var nimbusMessage = new NimbusMessage(destinationPath, payload);
            var expiresAfter = _clock.UtcNow.AddSafely(_timeToLive.Value);
            var currentDispatchContext = _dispatchContextManager.GetCurrentDispatchContext();
            nimbusMessage.PrecedingMessageId = currentDispatchContext.ResultOfMessageId;
            nimbusMessage.CorrelationId = currentDispatchContext.CorrelationId;
            nimbusMessage.From = _replyQueueName;
            nimbusMessage.ExpiresAfter = expiresAfter;

            payload?.GetType().GetProperties()
                    .Where(p => p.HasAttribute<FilterProperty>())
                    .Do(p => nimbusMessage.Properties[p.Name] = p.GetValue(payload))
                    .Done();

            return Task.FromResult(nimbusMessage);
        }
示例#44
0
        public void Inject(object handlerOrInterceptor, NimbusMessage nimbusMessage)
        {
            var requireBus = handlerOrInterceptor as IRequireBus;
            if (requireBus != null)
            {
                requireBus.Bus = Bus;
            }

            var requiresBusId = handlerOrInterceptor as IRequireBusId;
            if (requiresBusId != null)
            {
                requiresBusId.BusId = Bus.InstanceId;
            }

            var requireDispatchContext = handlerOrInterceptor as IRequireDispatchContext;
            if (requireDispatchContext != null)
            {
                requireDispatchContext.DispatchContext = _dispatchContextManager.GetCurrentDispatchContext();
            }

            var requireNimbusMessage = handlerOrInterceptor as IRequireNimbusMessage;
            if (requireNimbusMessage != null)
            {
                requireNimbusMessage.NimbusMessage = nimbusMessage;
            }

            var requireDateTime = handlerOrInterceptor as IRequireDateTime;
            if (requireDateTime != null)
            {
                requireDateTime.UtcNow = () => _clock.UtcNow;
            }

            var requireLargeMessageBodyStore = handlerOrInterceptor as IRequireLargeMessageBodyStore;
            if (requireLargeMessageBodyStore != null)
            {
                requireLargeMessageBodyStore.LargeMessageBodyStore = _largeMessageBodyStore;
            }

            var requireMessageProperties = handlerOrInterceptor as IRequireMessageProperties;
            if (requireMessageProperties != null)
            {
                var properties = nimbusMessage.ExtractProperties();
                requireMessageProperties.MessageProperties = properties;
            }
        }
示例#45
0
        private async Task PostToDeadLetterOffice(NimbusMessage message)
        {
            if (!_enableDeadLetteringOnMessageExpiration)
            {
                return;
            }

            _logger.Debug("Posting message to dead letter office.");

            try
            {
                await _deadLetterOffice.Post(message);
            }
            catch (Exception exc)
            {
                _logger.Error(exc, "Failed to post message to dead letter office.");
            }
        }
        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);
        }
示例#47
0
        public Task <NimbusMessage> Create(string destinationPath, [AllowNull] object payload)
        {
            var nimbusMessage          = new NimbusMessage(destinationPath, payload);
            var expiresAfter           = _clock.UtcNow.AddSafely(_timeToLive.Value);
            var currentDispatchContext = _dispatchContextManager.GetCurrentDispatchContext();

            nimbusMessage.PrecedingMessageId = currentDispatchContext.ResultOfMessageId;
            nimbusMessage.CorrelationId      = currentDispatchContext.CorrelationId;
            nimbusMessage.From         = _replyQueueName;
            nimbusMessage.ExpiresAfter = expiresAfter;

            payload?.GetType().GetProperties()
            .Where(p => p.HasAttribute <FilterProperty>())
            .Do(p => nimbusMessage.Properties[p.Name] = p.GetValue(payload))
            .Done();

            return(Task.FromResult(nimbusMessage));
        }
        public IInboundInterceptor[] CreateInterceptors(IDependencyResolverScope scope, object handler, object message, NimbusMessage nimbusMessage)
        {
            var globalInterceptors = GetGlobalInterceptorTypes();
            var classLevelInterceptors = GetClassLevelInterceptorTypes(handler);
            var methodLevelInterceptors = GetMethodLevelInterceptorTypes(handler, message);

            var interceptors = new Type[0]
                .Union(globalInterceptors)
                .Union(classLevelInterceptors)
                .Union(methodLevelInterceptors)
                .DistinctBy(t => t.FullName)
                .Select(t => (IInboundInterceptor) scope.Resolve(t))
                .Do(interceptor => _propertyInjector.Inject(interceptor, nimbusMessage))
                .OrderByDescending(i => i.Priority)
                .ThenBy(i => i.GetType().FullName)
                .ToArray();

            return interceptors;
        }
示例#49
0
        public Task<BrokeredMessage> BuildBrokeredMessage(NimbusMessage message)
        {
            return Task.Run(async () =>
                                  {
                                      BrokeredMessage brokeredMessage;
                                      var messageBodyBytes = SerializeNimbusMessage(message);

                                      if (messageBodyBytes.Length > _maxLargeMessageSize)
                                      {
                                          var errorMessage =
                                              "Message body size of {0} is larger than the permitted maximum of {1}. You need to change this in your bus configuration settings if you want to send messages this large."
                                                  .FormatWith(messageBodyBytes.Length, _maxLargeMessageSize.Value);
                                          throw new BusException(errorMessage);
                                      }

                                      if (messageBodyBytes.Length > _maxSmallMessageSize)
                                      {
                                          brokeredMessage = new BrokeredMessage();
                                          var expiresAfter = message.ExpiresAfter;
                                          var blobIdentifier = await _largeMessageBodyStore.Store(message.MessageId, messageBodyBytes, expiresAfter);
                                          brokeredMessage.Properties[MessagePropertyKeys.LargeBodyBlobIdentifier] = blobIdentifier;
                                      }
                                      else
                                      {
                                          brokeredMessage = new BrokeredMessage(messageBodyBytes);
                                      }

                                      var currentDispatchContext = _dispatchContextManager.GetCurrentDispatchContext();
                                      brokeredMessage.MessageId = message.MessageId.ToString();
                                      brokeredMessage.CorrelationId = currentDispatchContext.CorrelationId.ToString();
                                      brokeredMessage.ReplyTo = message.From;
                                      brokeredMessage.TimeToLive = message.ExpiresAfter.Subtract(DateTimeOffset.UtcNow);
                                      brokeredMessage.ScheduledEnqueueTimeUtc = message.DeliverAfter.UtcDateTime;

                                      foreach (var property in message.Properties)
                                      {
                                          brokeredMessage.Properties[property.Key] = property.Value;
                                      }

                                      return brokeredMessage;
                                  });
        }
示例#50
0
        public Task <BrokeredMessage> BuildBrokeredMessage(NimbusMessage message)
        {
            return(Task.Run(async() =>
            {
                BrokeredMessage brokeredMessage;
                var messageBodyBytes = SerializeNimbusMessage(message);

                if (messageBodyBytes.Length > _maxLargeMessageSize)
                {
                    var errorMessage =
                        "Message body size of {0} is larger than the permitted maximum of {1}. You need to change this in your bus configuration settings if you want to send messages this large."
                        .FormatWith(messageBodyBytes.Length, _maxLargeMessageSize.Value);
                    throw new BusException(errorMessage);
                }

                if (messageBodyBytes.Length > _maxSmallMessageSize)
                {
                    brokeredMessage = new BrokeredMessage();
                    var expiresAfter = message.ExpiresAfter;
                    var blobIdentifier = await _largeMessageBodyStore.Store(message.MessageId, messageBodyBytes, expiresAfter);
                    brokeredMessage.Properties[MessagePropertyKeys.LargeBodyBlobIdentifier] = blobIdentifier;
                }
                else
                {
                    brokeredMessage = new BrokeredMessage(messageBodyBytes);
                }

                var currentDispatchContext = _dispatchContextManager.GetCurrentDispatchContext();
                brokeredMessage.MessageId = message.MessageId.ToString();
                brokeredMessage.CorrelationId = currentDispatchContext.CorrelationId.ToString();
                brokeredMessage.ReplyTo = message.From;
                brokeredMessage.TimeToLive = message.ExpiresAfter.Subtract(DateTimeOffset.UtcNow);
                brokeredMessage.ScheduledEnqueueTimeUtc = message.DeliverAfter.UtcDateTime;

                foreach (var property in message.Properties)
                {
                    brokeredMessage.Properties[property.Key] = property.Value;
                }

                return brokeredMessage;
            }));
        }
示例#51
0
        public async Task Send(NimbusMessage message)
        {
            var database = _databaseFunc();

            var subscribersRedisKey = Subscription.TopicSubscribersRedisKeyFor(_topicPath);
            var subscribers         = database.SetMembers(subscribersRedisKey)
                                      .Select(s => s.ToString())
                                      .ToArray();

            await subscribers
            .Select(subscriberPath => Task.Run(() =>
            {
                var clone = (NimbusMessage)_serializer.Deserialize(_serializer.Serialize(message), typeof(NimbusMessage));
                clone.DeliverTo = subscriberPath;
                var serialized = _serializer.Serialize(clone);
                database.ListRightPush(subscriberPath, serialized);
                database.Publish(subscriberPath, string.Empty);
            }).ConfigureAwaitFalse())
            .WhenAll();
        }
示例#52
0
        public async Task Send(NimbusMessage message)
        {
            var database = _databaseFunc();

            var subscribersRedisKey = Subscription.TopicSubscribersRedisKeyFor(_topicPath);
            var subscribers = database.SetMembers(subscribersRedisKey)
                                      .Select(s => s.ToString())
                                      .ToArray();

            await subscribers
                .Select(subscriberPath => Task.Run(() =>
                                                   {
                                                       var clone = (NimbusMessage) _serializer.Deserialize(_serializer.Serialize(message), typeof (NimbusMessage));
                                                       clone.DeliverTo = subscriberPath;
                                                       var serialized = _serializer.Serialize(clone);
                                                       database.ListRightPush(subscriberPath, serialized);
                                                       database.Publish(subscriberPath, string.Empty);
                                                   }).ConfigureAwaitFalse())
                .WhenAll();
        }
示例#53
0
        public async Task DeliverAfter(NimbusMessage message, DateTimeOffset deliveryTime)
        {
            if (await _queueManager.QueueExists(message.DeliverTo))
            {
                message.DeliverAfter = deliveryTime;
                var messageSender = await _queueManager.CreateMessageSender(message.DeliverTo);
                var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);
                await messageSender.SendAsync(brokeredMessage);
                return;
            }

            if (await _queueManager.TopicExists(message.DeliverTo))
            {
                message.DeliverAfter = deliveryTime;
                var topicSender = await _queueManager.CreateTopicSender(message.DeliverTo);
                var brokeredMessage2 = await _brokeredMessageFactory.BuildBrokeredMessage(message);
                await topicSender.SendAsync(brokeredMessage2);
                return;
            }

            throw new NotSupportedException("Message redelivery was requested but neither a queue path nor a topic path could be found.");
        }
 public DateTimeOffset CalculateNextRetryTime(NimbusMessage message)
 {
     return message.DeliveryAttempts.Max().AddSeconds(1);
 }
示例#55
0
        private async Task Dispatch(NimbusMessage message)
        {
            DispatchLoggingContext.NimbusMessage = message;

            // Early exit: have we pre-fetched this message and had our lock already expire? If so, just
            // bail - it will already have been picked up by someone else.
            var now = _clock.UtcNow;
            if (message.ExpiresAfter <= now)
            {
                _logger.Warn(
                    "Message {MessageId} appears to have already expired (expires after {ExpiresAfter} and it is now {Now}) so we're not dispatching it. Watch out for clock drift between your hosts!",
                    message.MessageId,
                    message.ExpiresAfter,
                    now);

                await PostToDeadLetterOffice(message);

                return;
            }

            try
            {
                try
                {
                    _logger.Debug("Dispatching message {MessageId}", message.MessageId);
                    message.RecordDeliveryAttempt(now);
                    using (_dispatchContextManager.StartNewDispatchContext(new SubsequentDispatchContext(message)))
                    {
                        await _messageDispatcher.Dispatch(message);
                    }
                    _logger.Info("Dispatched message {MessageId}", message.MessageId);
                    return;
                }
                catch (Exception exc)
                {
                    _logger.Warn(exc, "Dispatch failed for message {MessageId}", message.MessageId);
                }

                var numDeliveryAttempts = message.DeliveryAttempts.Count();
                if (numDeliveryAttempts >= _maxDeliveryAttempts)
                {
                    _logger.Error("Too many delivery attempts ({DeliveryAttempts}) for message {MessageId}.", numDeliveryAttempts, message.MessageId);
                    await PostToDeadLetterOffice(message);
                }
                else
                {
                    try
                    {
                        var nextDeliveryTime = _deliveryRetryStrategy.CalculateNextRetryTime(message);
                        _logger.Info("Re-enqueuing message {MessageId} for attempt {DeliveryAttempts} at delivery at {DeliveryTime}",
                                     message.MessageId,
                                     numDeliveryAttempts + 1,
                                     nextDeliveryTime);
                        await _delayedDeliveryService.DeliverAfter(message, nextDeliveryTime);
                    }
                    catch (Exception exc)
                    {
                        _logger.Error(exc, "Failed to re-enqueue message {MessageId} for re-delivery.", message.MessageId);
                    }
                }
            }
            catch (Exception exc)
            {
                _logger.Error(exc, "Unhandled exception in message pump");
            }
        }
示例#56
0
        private async Task PostToDeadLetterOffice(NimbusMessage message)
        {
            if (!_enableDeadLetteringOnMessageExpiration) return;

            _logger.Debug("Posting message to dead letter office.");

            try
            {
                await _deadLetterOffice.Post(message);
            }
            catch (Exception exc)
            {
                _logger.Error(exc, "Failed to post message to dead letter office.");
            }
        }
 public async Task Post(NimbusMessage message)
 {
     var messageSender = await _queueManager.CreateDeadQueueMessageSender();
     var brokeredMessage = await _brokeredMessageFactory.BuildBrokeredMessage(message);
     await messageSender.SendAsync(brokeredMessage);
 }
 public Task Post(NimbusMessage message)
 {
     return Task.Run(() => _messages.Add(message)).ConfigureAwaitFalse();
 }
 public SubsequentDispatchContext(NimbusMessage nimbusMessage)
 {
     DispatchId = Guid.NewGuid();
     CorrelationId = nimbusMessage.CorrelationId;
     _resultOfMessageId = nimbusMessage.MessageId;
 }
 private async Task<BrokeredMessage> When(BrokeredMessageFactory brokeredMessageFactory)
 {
     var bigFatObject = new string(Enumerable.Range(0, 256*1024).Select(i => '.').ToArray());
     var nimbusMessage = new NimbusMessage("noPath", bigFatObject);
     return await brokeredMessageFactory.BuildBrokeredMessage(nimbusMessage);
 }