static SendMessageBatchRequestEntry ToBatchEntry(this SqsPreparedMessage message, string batchEntryId) { return(new SendMessageBatchRequestEntry(batchEntryId, message.Body) { MessageAttributes = message.MessageAttributes, MessageGroupId = message.MessageGroupId, MessageDeduplicationId = message.MessageDeduplicationId, DelaySeconds = message.DelaySeconds }); }
public static SendMessageRequest ToRequest(this SqsPreparedMessage message) { return(new SendMessageRequest(message.QueueUrl, message.Body) { MessageGroupId = message.MessageGroupId, MessageDeduplicationId = message.MessageDeduplicationId, MessageAttributes = message.MessageAttributes, DelaySeconds = message.DelaySeconds }); }
public static IReadOnlyList <BatchEntry> Batch(IEnumerable <SqsPreparedMessage> preparedMessages) { var allBatches = new List <BatchEntry>(); var currentDestinationBatches = new Dictionary <string, SqsPreparedMessage>(); var groupByDestination = preparedMessages.GroupBy(m => m.QueueUrl, StringComparer.Ordinal); foreach (var group in groupByDestination) { SqsPreparedMessage firstMessage = null; var payloadSize = 0L; foreach (var message in group) { firstMessage = firstMessage ?? message; // Assumes the size was already calculated by the dispatcher var size = message.Size; payloadSize += size; if (payloadSize > TransportConfiguration.MaximumMessageSize) { allBatches.Add(message.ToBatchRequest(currentDestinationBatches)); currentDestinationBatches.Clear(); payloadSize = size; } // we don't have to recheck payload size here because the support layer checks that a request can always fit 256 KB size limit // we can't take MessageId because batch request ID can only contain alphanumeric characters, hyphen and underscores, message id could be overloaded currentDestinationBatches.Add(Guid.NewGuid().ToString(), message); var currentCount = currentDestinationBatches.Count; if (currentCount != 0 && currentCount % TransportConfiguration.MaximumItemsInBatch == 0) { allBatches.Add(message.ToBatchRequest(currentDestinationBatches)); currentDestinationBatches.Clear(); payloadSize = 0; } } if (currentDestinationBatches.Count > 0) { allBatches.Add(firstMessage.ToBatchRequest(currentDestinationBatches)); currentDestinationBatches.Clear(); } } return(allBatches); }
public static BatchEntry ToBatchRequest(this SqsPreparedMessage message, Dictionary <string, SqsPreparedMessage> batchEntries) { var preparedMessagesBydId = batchEntries.ToDictionary(x => x.Key, x => x.Value); var batchRequestEntries = new List <SendMessageBatchRequestEntry>(); foreach (var kvp in preparedMessagesBydId) { batchRequestEntries.Add(kvp.Value.ToBatchEntry(kvp.Key)); } return(new BatchEntry { BatchRequest = new SendMessageBatchRequest(message.QueueUrl, batchRequestEntries), PreparedMessagesBydId = preparedMessagesBydId }); }
async Task SendMessage(SqsPreparedMessage message) { try { await sqsClient.SendMessageAsync(message.ToRequest()) .ConfigureAwait(false); } catch (QueueDoesNotExistException e) when(message.OriginalDestination != null) { throw new QueueDoesNotExistException($"Destination '{message.OriginalDestination}' doesn't support delayed messages longer than {TimeSpan.FromSeconds(configuration.DelayedDeliveryQueueDelayTime)}. To enable support for longer delays, call '.UseTransport<SqsTransport>().UnrestrictedDurationDelayedDelivery()' on the '{message.OriginalDestination}' endpoint.", e); } catch (Exception ex) { Logger.Error($"Error while sending message, with MessageId '{message.MessageId}', to '{message.Destination}'", ex); throw; } }
async Task ApplyUnicastOperationMappingIfNecessary(UnicastTransportOperation transportOperation, SqsPreparedMessage sqsPreparedMessage, long delaySeconds, string messageId) { if (transportOperation == null || sqsPreparedMessage == null) { return; } var delayLongerThanConfiguredDelayedDeliveryQueueDelayTime = configuration.IsDelayedDeliveryEnabled && delaySeconds > configuration.DelayedDeliveryQueueDelayTime; if (delayLongerThanConfiguredDelayedDeliveryQueueDelayTime) { sqsPreparedMessage.OriginalDestination = transportOperation.Destination; sqsPreparedMessage.Destination = $"{transportOperation.Destination}{TransportConfiguration.DelayedDeliveryQueueSuffix}"; sqsPreparedMessage.QueueUrl = await queueCache.GetQueueUrl(sqsPreparedMessage.Destination) .ConfigureAwait(false); sqsPreparedMessage.MessageDeduplicationId = messageId; sqsPreparedMessage.MessageGroupId = messageId; sqsPreparedMessage.MessageAttributes[TransportHeaders.DelaySeconds] = new MessageAttributeValue { StringValue = delaySeconds.ToString(), DataType = "String" }; } else { sqsPreparedMessage.Destination = transportOperation.Destination; sqsPreparedMessage.QueueUrl = await queueCache.GetQueueUrl(sqsPreparedMessage.Destination) .ConfigureAwait(false); if (delaySeconds > 0) { sqsPreparedMessage.DelaySeconds = Convert.ToInt32(delaySeconds); } } }
async Task SendMessageForBatch(SqsPreparedMessage message, int batchNumber, int totalBatches) { await SendMessage(message).ConfigureAwait(false); Logger.Info($"Retried message with MessageId {message.MessageId} that failed in batch '{batchNumber}/{totalBatches}'."); }