コード例 #1
0
        private async Task UpdateMessageVisibilityTimeout(
            IQueueMessageContext messageContext,
            Message typedMessage,
            Exception lastException,
            CancellationToken cancellationToken)
        {
            if (TryGetApproxReceiveCount(messageContext.Message.Attributes, out int approxReceiveCount))
            {
                var visibilityTimeout =
                    _messageBackoffStrategy.GetBackoffDuration(typedMessage,
                                                               approxReceiveCount,
                                                               lastException);

                try
                {
                    await messageContext.ChangeMessageVisibilityAsync(visibilityTimeout, cancellationToken)
                    .ConfigureAwait(false);
                }
                catch (AmazonServiceException ex)
                {
                    _logger.LogError(
                        ex,
                        "Failed to update message visibility timeout by {VisibilityTimeout} seconds for message with receipt handle '{ReceiptHandle}'.",
                        visibilityTimeout,
                        messageContext.Message.ReceiptHandle);

                    _messagingMonitor.HandleError(ex, messageContext.Message);
                }
            }
        }
コード例 #2
0
        DeserializeMessage(IQueueMessageContext messageContext, CancellationToken cancellationToken)
        {
            try
            {
                var messageWithAttributes = _serializationRegister.DeserializeMessage(messageContext.Message.Body);
                return(true, messageWithAttributes.Message, messageWithAttributes.MessageAttributes);
            }
            catch (MessageFormatNotSupportedException ex)
            {
                _logger.LogTrace(
                    "Could not handle message with Id '{MessageId}' because a deserializer for the content is not configured. Message body: '{MessageBody}'.",
                    messageContext.Message.MessageId,
                    messageContext.Message.Body);

                await messageContext.DeleteMessageFromQueueAsync(cancellationToken).ConfigureAwait(false);

                _messagingMonitor.HandleError(ex, messageContext.Message);

                return(false, null, null);
            }
#pragma warning disable CA1031
            catch (Exception ex)
#pragma warning restore CA1031
            {
                _logger.LogError(
                    ex,
                    "Error deserializing message with Id '{MessageId}' and body '{MessageBody}'.",
                    messageContext.Message.MessageId,
                    messageContext.Message.Body);

                _messagingMonitor.HandleError(ex, messageContext.Message);

                return(false, null, null);
            }
        }
コード例 #3
0
    /// <summary>
    /// Starts the receive buffer until it's cancelled by the stopping token.
    /// </summary>
    /// <param name="stoppingToken">A <see cref="CancellationToken"/> that will stop the buffer when signalled.</param>
    /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation to receive the messages.</returns>
    public async Task RunAsync(CancellationToken stoppingToken)
    {
        await Task.Yield();

        ChannelWriter <IQueueMessageContext> writer = _channel.Writer;

        try
        {
            while (true)
            {
                stoppingToken.ThrowIfCancellationRequested();

                using (_monitor.MeasureThrottle())
                {
                    bool canWrite = await writer.WaitToWriteAsync(stoppingToken).ConfigureAwait(false);

                    if (!canWrite)
                    {
                        break;
                    }
                }

                IList <Message> messages;
                using (_monitor.MeasureReceive(_sqsQueueReader.QueueName, _sqsQueueReader.RegionSystemName))
                {
                    messages = await GetMessagesAsync(_prefetch, stoppingToken).ConfigureAwait(false);

                    if (messages == null)
                    {
                        continue;
                    }
                }

                if (_logger.IsEnabled(LogLevel.Trace))
                {
                    _logger.LogTrace("Downloaded {MessageCount} messages from queue {QueueName}.", messages.Count, _sqsQueueReader.QueueName);
                }

                foreach (Message message in messages)
                {
                    IQueueMessageContext messageContext = _sqsQueueReader.ToMessageContext(message);

                    await writer.WriteAsync(messageContext, stoppingToken).ConfigureAwait(false);
                }
            }
        }
        finally
        {
            _logger.LogInformation("Receive buffer for queue {QueueName} has completed, shutting down channel",
                                   _sqsQueueReader.Uri);
            writer.Complete();
        }
    }
コード例 #4
0
        /// <summary>
        /// Starts the receive buffer until it's cancelled by the stopping token.
        /// </summary>
        /// <param name="stoppingToken">A <see cref="CancellationToken"/> that will stop the buffer when signalled.</param>
        /// <returns>A <see cref="Task{TResult}"/> representing the asynchronous operation to receive the messages.</returns>
        public async Task RunAsync(CancellationToken stoppingToken)
        {
            await Task.Yield();

            ChannelWriter <IQueueMessageContext> writer = _channel.Writer;

            try
            {
                while (true)
                {
                    stoppingToken.ThrowIfCancellationRequested();

                    using (_monitor.MeasureThrottle())
                    {
                        bool canWrite = await writer.WaitToWriteAsync(stoppingToken).ConfigureAwait(false);

                        if (!canWrite)
                        {
                            break;
                        }
                    }

                    IList <Message> messages;
                    using (_monitor.MeasureReceive(_sqsQueueReader.QueueName, _sqsQueueReader.RegionSystemName))
                    {
                        messages = await GetMessagesAsync(_prefetch, stoppingToken).ConfigureAwait(false);

                        if (messages == null)
                        {
                            continue;
                        }
                    }

                    foreach (Message message in messages)
                    {
                        IQueueMessageContext messageContext = _sqsQueueReader.ToMessageContext(message);

                        // Complete all messages in the batch, rather than observing the CancellationToken to stop
                        await writer.WriteAsync(messageContext, CancellationToken.None).ConfigureAwait(false);
                    }
                }
            }
            finally
            {
                _logger.LogInformation("Receive buffer for queue {QueueName} has completed, shutting down channel",
                                       _sqsQueueReader.Uri);
                writer.Complete();
            }
        }
コード例 #5
0
        public async Task DispatchMessageAsync(
            IQueueMessageContext messageContext,
            CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            (bool success, Message typedMessage, MessageAttributes attributes) =
                await DeserializeMessage(messageContext, cancellationToken).ConfigureAwait(false);

            if (!success)
            {
                return;
            }

            var messageType = typedMessage.GetType();
            var middleware  = _middlewareMap.Get(messageContext.QueueName, messageType);

            if (middleware == null)
            {
                _logger.LogError(
                    "Failed to dispatch. Middleware for message of type '{MessageTypeName}' not found in middleware map.",
                    typedMessage.GetType().FullName);
                return;
            }

            var handleContext = new HandleMessageContext(
                messageContext.QueueName,
                messageContext.Message,
                typedMessage,
                messageType,
                messageContext,
                messageContext,
                messageContext.QueueUri,
                attributes);

            await middleware.RunAsync(handleContext, null, cancellationToken)
            .ConfigureAwait(false);
        }
コード例 #6
0
        public async Task DispatchMessageAsync(
            IQueueMessageContext messageContext,
            CancellationToken cancellationToken)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            (bool success, Message typedMessage, MessageAttributes attributes) =
                await DeserializeMessage(messageContext, cancellationToken).ConfigureAwait(false);

            if (!success)
            {
                return;
            }

            var       handlingSucceeded = false;
            Exception lastException     = null;

            try
            {
                if (typedMessage != null)
                {
                    _messageContextAccessor.MessageContext =
                        new MessageContext(messageContext.Message, messageContext.QueueUri, attributes);

                    handlingSucceeded = await CallMessageHandler(messageContext.QueueName, typedMessage)
                                        .ConfigureAwait(false);
                }

                if (handlingSucceeded)
                {
                    await messageContext.DeleteMessageFromQueueAsync(cancellationToken).ConfigureAwait(false);
                }
            }
#pragma warning disable CA1031
            catch (Exception ex)
#pragma warning restore CA1031
            {
                _logger.LogError(
                    ex,
                    "Error handling message with Id '{MessageId}' and body '{MessageBody}'.",
                    messageContext.Message.MessageId,
                    messageContext.Message.Body);

                if (typedMessage != null)
                {
                    _messagingMonitor.HandleException(typedMessage.GetType());
                }

                _messagingMonitor.HandleError(ex, messageContext.Message);

                lastException = ex;
            }
            finally
            {
                try
                {
                    if (!handlingSucceeded && _messageBackoffStrategy != null)
                    {
                        await UpdateMessageVisibilityTimeout(messageContext,
                                                             typedMessage,
                                                             lastException,
                                                             cancellationToken).ConfigureAwait(false);
                    }
                }
                finally
                {
                    _messageContextAccessor.MessageContext = null;
                }
            }
        }
コード例 #7
0
ファイル: FakeDispatcher.cs プロジェクト: slang25/JustSaying
 public Task DispatchMessageAsync(IQueueMessageContext messageContext, CancellationToken cancellationToken)
 {
     _spy?.Invoke();
     DispatchedMessages.Add(messageContext);
     return(Task.CompletedTask);
 }