private Task StartMessageReceiverInternal(string queueName, MessageReceiverOptions options, Func <ISQSMessage, Task> asyncMessageProcessor, CancellationToken cancellationToken) { if (options.MaxNumberOfMessagesPerPoll > 10 || options.MaxNumberOfMessagesPerPoll < 1) { throw new ArgumentException($"nameof(options.MaxNumberOfMessagesPerPoll) must be between 1 and 10", nameof(options.MaxNumberOfMessagesPerPoll)); } if (options.MessagePollWaitTimeSeconds < 0 || options.MessagePollWaitTimeSeconds > 20) { throw new ArgumentException($"{nameof(options.MessagePollWaitTimeSeconds)} must be within the range 0 to 20.", nameof(options.MessagePollWaitTimeSeconds)); } if (options.VisibilityTimeoutSeconds.HasValue && options.VisibilityTimeoutSeconds.Value < 0) { throw new ArgumentException($"{nameof(options.VisibilityTimeoutSeconds)} must be 0 or greater, or null.", nameof(options.MessagePollWaitTimeSeconds)); } return(Task.Run(async() => { while (!cancellationToken.IsCancellationRequested) { var messageAttributesQuery = new List <string> { "All" }; var receiveMessageResponse = await ReceiveMessageAsync(queueName, waitTimeSeconds: options.MessagePollWaitTimeSeconds, maxNumberOfMessages: options.MaxNumberOfMessagesPerPoll, visibilityTimeoutSeconds: options.VisibilityTimeoutSeconds, messageAttributeNames: messageAttributesQuery); foreach (var message in receiveMessageResponse.Messages) { var sqsMessage = new SQSMessage(this, queueName, message.ReceiptHandle) { Body = message.Body }; if (message.MessageAttributes.Count > 0) { var messageAttributes = new Dictionary <string, string>(); foreach (var messageAttribute in message.MessageAttributes) { if (messageAttribute.Value.StringValue != null) { messageAttributes.Add(messageAttribute.Key, messageAttribute.Value.StringValue); } } sqsMessage.MessageAttributes = messageAttributes; } await asyncMessageProcessor(sqsMessage); } } }, cancellationToken)); }
private Task StartMessageReceiverInternal(string queueName, MessageReceiverOptions options, Func <string, Task <bool> > asyncMessageProcessor, CancellationToken cancellationToken) { if (options.MaxNumberOfMessagesPerPoll > 10 || options.MaxNumberOfMessagesPerPoll < 1) { throw new ArgumentException($"nameof(options.MaxNumberOfMessagesPerPoll) must be between 1 and 10", nameof(options.MaxNumberOfMessagesPerPoll)); } if (options.MessagePollWaitTimeSeconds < 0 || options.MessagePollWaitTimeSeconds > 20) { throw new ArgumentException($"{nameof(options.MessagePollWaitTimeSeconds)} must be within the range 0 to 20.", nameof(options.MessagePollWaitTimeSeconds)); } if (options.VisibilityTimeoutSeconds.HasValue && options.VisibilityTimeoutSeconds.Value < 0) { throw new ArgumentException($"{nameof(options.VisibilityTimeoutSeconds)} must be 0 or greater, or null.", nameof(options.MessagePollWaitTimeSeconds)); } if (options.WaitForQueue) { WaitForQueue(queueName, options, cancellationToken); } return(Task.Run(async() => { while (!cancellationToken.IsCancellationRequested) { var receiveMessageResponse = await ReceiveMessageAsync(queueName, waitTimeSeconds: options.MessagePollWaitTimeSeconds, maxNumberOfMessages: options.MaxNumberOfMessagesPerPoll, visibilityTimeoutSeconds: options.VisibilityTimeoutSeconds); foreach (var message in receiveMessageResponse.Messages) { var success = await asyncMessageProcessor(message.Body); if (success) { await DeleteMessageAsync(queueName, message.ReceiptHandle); } } } }, cancellationToken)); }
/// <summary> /// Synchronously waits for a queue to be available. /// </summary> private void WaitForQueue(string queueName, MessageReceiverOptions options, CancellationToken cancellationToken) { for (var i = 0; i < options.WaitForQueueTimeoutSeconds; i++) { try { GetQueueUrlAsync(queueName).GetAwaiter().GetResult(); return; } catch (QueueDoesNotExistException) { Task.Delay(1000, cancellationToken).Wait(cancellationToken); } } throw new QueueDoesNotExistException($"Queue {queueName} does still not exist after waiting for {options.WaitForQueueTimeoutSeconds} seconds."); }
/// <summary> /// Starts a long running process that checks the queue for any new messages, and handles the messages on the queue in the processor specified. /// </summary> /// <param name="queueName">The name of the queue</param> /// <param name="options">Options for the receiver behaviour.</param> /// <param name="asyncMessageProcessor">The message processor which will handle the message picked from the queue</param> /// <param name="cancellationToken">The receiver process will check the status of this token and cancel the long running process if cancellation is requested.</param> /// <returns></returns> public Task StartMessageReceiver(string queueName, MessageReceiverOptions options, Func <string, Task <bool> > asyncMessageProcessor, CancellationToken cancellationToken) { return(StartMessageReceiverInternal(queueName, options, asyncMessageProcessor, cancellationToken)); }
/// <summary> /// Starts a long running process that checks the queue for any new messages, and handles the messages on the queue in the processor specified. /// /// Message should be explicitly acked to be removed from queue. /// </summary> /// <param name="queueName">The name of the queue</param> /// <param name="options">Options for the receiver behaviour.</param> /// <param name="messageProcessor">The message processor which will handle the message picked from the queue</param> /// <param name="cancellationToken">The receiver process will check the status of this token and cancel the long running process if cancellation is requested.</param> /// <returns></returns> public Task StartMessageReceiver(string queueName, MessageReceiverOptions options, Action <ISQSMessage> messageProcessor, CancellationToken cancellationToken) { return(StartMessageReceiverInternal(queueName, options, async(arg) => messageProcessor(arg), cancellationToken)); }