public async Task Send(UnicastTransportOperation operation, CancellationToken cancellationToken = default) { if (logger.IsDebugEnabled) { logger.DebugFormat("Sending message (ID: '{0}') to {1}", operation.Message.MessageId, operation.Destination); } if (NativeDelayDeliveryPersistence.IsDelayedMessage(operation, out var dueDate)) { await nativeDelayDeliveryPersistence.ScheduleAt(operation, dueDate, cancellationToken).ConfigureAwait(false); return; } // The destination might be in a queue@destination format var destination = operation.Destination; var messageIntent = operation.GetMessageIntent(); var queueAddress = QueueAddress.Parse(destination, messageIntent == MessageIntentEnum.Reply); var queueServiceClient = addressing.Map(queueAddress, messageIntent); var queueName = addressGenerator.GetQueueName(queueAddress.QueueName); var sendQueue = queueServiceClient.GetQueueClient(queueName); if (!await ExistsAsync(sendQueue, cancellationToken).ConfigureAwait(false)) { throw new QueueNotFoundException(queueAddress.ToString(), $"Destination queue '{queueAddress}' does not exist. This queue may have to be created manually.", null); } var toBeReceived = operation.Properties.DiscardIfNotReceivedBefore; var timeToBeReceived = toBeReceived != null && toBeReceived.MaxTime < TimeSpan.MaxValue ? toBeReceived.MaxTime : (TimeSpan?)null; if (timeToBeReceived.HasValue) { if (timeToBeReceived.Value == TimeSpan.Zero) { var messageType = operation.Message.Headers[Headers.EnclosedMessageTypes].Split(',').First(); logger.WarnFormat("TimeToBeReceived is set to zero for message of type '{0}'. Cannot send operation.", messageType); return; } // user explicitly specified TimeToBeReceived that is not TimeSpan.MaxValue - fail if (timeToBeReceived.Value > CloudQueueMessageMaxTimeToLive && timeToBeReceived.Value != TimeSpan.MaxValue) { var messageType = operation.Message.Headers[Headers.EnclosedMessageTypes].Split(',').First(); throw new InvalidOperationException($"TimeToBeReceived is set to more than 30 days for message type '{messageType}'."); } var seconds = Convert.ToInt64(Math.Ceiling(timeToBeReceived.Value.TotalSeconds)); if (seconds <= 0) { throw new Exception($"Message cannot be sent with a provided delay of {timeToBeReceived.Value.TotalMilliseconds} ms."); } timeToBeReceived = TimeSpan.FromSeconds(seconds); } var wrapper = BuildMessageWrapper(operation, queueAddress); await Send(wrapper, sendQueue, timeToBeReceived ?? CloudQueueMessageMaxTimeToLive, cancellationToken).ConfigureAwait(false); }
public Dispatcher(QueueAddressGenerator addressGenerator, AzureStorageAddressingSettings addressing, MessageWrapperSerializer serializer, NativeDelayDeliveryPersistence nativeDelayDeliveryPersistence, ISubscriptionStore subscriptionStore) { this.subscriptionStore = subscriptionStore; this.addressGenerator = addressGenerator; this.addressing = addressing; this.serializer = serializer; this.nativeDelayDeliveryPersistence = nativeDelayDeliveryPersistence; }