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); } }
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(); }
public virtual async Task OnRequestSendingError <TBusRequest, TBusResponse>(IBusRequest <TBusRequest, TBusResponse> busRequest, NimbusMessage nimbusMessage, Exception exception) where TBusRequest : IBusRequest <TBusRequest, TBusResponse> where TBusResponse : IBusResponse { }
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); } }
internal static TimeSpan GetRequestTimeout(this NimbusMessage message) { var requestTimeoutInMilliseconds = (int)message.Properties[MessagePropertyKeys.RequestTimeoutInMilliseconds]; var timeout = TimeSpan.FromMilliseconds(requestTimeoutInMilliseconds); return(timeout); }
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); }
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(); }
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(); }
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(); }
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; } }
public Task Post(NimbusMessage message) { return Task.Run(() => { var database = _databaseFunc(); var serialized = _serializer.Serialize(message); database.ListRightPush(_deadLetterOfficeRedisKey, serialized); }).ConfigureAwaitFalse(); }
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; }
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); }
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; }
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()); }
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); }
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 }); }
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); }
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); }
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); }
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); }
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; }
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); }
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); }
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; } }
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)); }
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(); }
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); }
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); }
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); }
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; }
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; }); }
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; })); }
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(); }
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(); }
public DateTimeOffset CalculateNextRetryTime(NimbusMessage message) { return message.DeliveryAttempts.Max().AddSeconds(1); }
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"); } }
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); }