Esempio n. 1
0
        /// <summary>
        /// Called by the message processing loop to process an individual message
        /// </summary>
        /// <param name="queuedMessage">The queued message to process</param>
        /// <param name="cancellationToken">A cancellation token that can be used by the caller
        /// to cancel message processing operation</param>
        /// <returns>Returns a task that completes when the queued message is processed</returns>
        protected virtual async Task ProcessQueuedMessage(QueuedMessage queuedMessage,
                                                          CancellationToken cancellationToken)
        {
            try
            {
                queuedMessage = queuedMessage.NextAttempt();
                var acknowledged = await HandleMessageReceived(queuedMessage, cancellationToken);

                if (acknowledged)
                {
                    await HandleMessageAcknowledged(queuedMessage, cancellationToken);

                    return;
                }

                await DiagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.MessageNotAcknowledged)
                {
                    Message = queuedMessage.Message,
                    Queue   = QueueName
                }.Build(), cancellationToken);

                if (queuedMessage.Attempts >= _maxAttempts)
                {
                    await HandleMaximumAttemptsExceeded(queuedMessage, cancellationToken);

                    return;
                }

                await HandleAcknowledgementFailure(queuedMessage);

                DiagnosticService.Emit(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.QueuedMessageRetry)
                {
                    Detail  = "Message not acknowledged; retrying in " + _retryDelay,
                    Message = queuedMessage.Message,
                    Queue   = QueueName
                }.Build());

                ScheduleRetry(queuedMessage, cancellationToken);
            }
            catch (Exception ex)
            {
                // Catch all.  Do not let any exceptions propagate outside of this method!
                DiagnosticService.Emit(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.QueuedMessageProcessingError)
                {
                    Detail    = "Unhandled exception processing queued message",
                    Message   = queuedMessage.Message,
                    Queue     = QueueName,
                    Exception = ex
                }.Build());
            }
        }
Esempio n. 2
0
        private async Task <bool> HandleMessageReceived(QueuedMessage queuedMessage, CancellationToken cancellationToken)
        {
            Message    message                 = null;
            var        acknowledged            = false;
            IPrincipal originalThreadPrincipal = null;

            try
            {
                originalThreadPrincipal = Thread.CurrentPrincipal;
                message       = queuedMessage.Message;
                queuedMessage = queuedMessage.NextAttempt();

                await DiagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.QueuedMessageAttempt)
                {
                    Detail = "Processing queued message (attempt " + queuedMessage.Attempts + " of " +
                             _maxAttempts + ")",
                    Message = message,
                    Queue   = QueueName
                }.Build(), cancellationToken);

                var context = new QueuedMessageContext(message, queuedMessage.Principal);

                Thread.CurrentPrincipal = context.Principal;
                cancellationToken.ThrowIfCancellationRequested();

                await _listener.MessageReceived(message, context, cancellationToken);

                if (_autoAcknowledge && !context.Acknowledged)
                {
                    await context.Acknowledge();
                }

                acknowledged = context.Acknowledged;
            }
            catch (Exception ex)
            {
                DiagnosticService.Emit(new DiagnosticEventBuilder(this, DiagnosticEventType.UnhandledException)
                {
                    Detail    = "Unhandled exception handling queued message",
                    Message   = message,
                    Queue     = QueueName,
                    Exception = ex
                }.Build());
            }
            finally
            {
                Thread.CurrentPrincipal = originalThreadPrincipal;
            }

            return(acknowledged);
        }
        /// <summary>
        /// Called by the message processing loop to process an individual message
        /// </summary>
        /// <param name="queuedMessage">The queued message to process</param>
        /// <param name="cancellationToken">A cancellation token that can be used by the caller
        /// to cancel message processing operation</param>
        /// <returns>Returns a task that completes when the queued message is processed</returns>
        protected virtual async Task ProcessQueuedMessage(QueuedMessage queuedMessage,
                                                          CancellationToken cancellationToken)
        {
            Exception exception = null;
            var       message   = queuedMessage.Message;
            var       principal = queuedMessage.Principal;

            // ReSharper disable once ConditionIsAlwaysTrueOrFalse

            queuedMessage = queuedMessage.NextAttempt();

            await DiagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.QueuedMessageAttempt)
            {
                Detail = "Processing queued message (attempt " + queuedMessage.Attempts + " of " + _maxAttempts +
                         ")",
                Message = message,
                Queue   = QueueName
            }.Build(), cancellationToken);

            var context = new QueuedMessageContext(message, principal);

            Thread.CurrentPrincipal = context.Principal;
            cancellationToken.ThrowIfCancellationRequested();
            try
            {
                await _listener.MessageReceived(message, context, cancellationToken);

                if (_autoAcknowledge && !context.Acknowledged)
                {
                    await context.Acknowledge();
                }
            }
            catch (Exception ex)
            {
                exception = ex;
                DiagnosticService.Emit(new DiagnosticEventBuilder(this, DiagnosticEventType.UnhandledException)
                {
                    Detail    = "Unhandled exception handling queued message",
                    Message   = message,
                    Queue     = QueueName,
                    Exception = ex
                }.Build());
            }

            var eventArgs = new MessageQueueEventArgs(QueueName, queuedMessage, exception);

            if (context.Acknowledged)
            {
                await DiagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.MessageAcknowledged)
                {
                    Message = message,
                    Queue   = QueueName
                }.Build(), cancellationToken);

                var messageAcknowledgedHandlers = MessageAcknowledged;
                if (messageAcknowledgedHandlers != null)
                {
                    await messageAcknowledgedHandlers(this, eventArgs);
                }
                return;
            }

            await DiagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.MessageNotAcknowledged)
            {
                Message = message,
                Queue   = QueueName
            }.Build(), cancellationToken);

            if (queuedMessage.Attempts >= _maxAttempts)
            {
                await DiagnosticService.EmitAsync(
                    new DiagnosticEventBuilder(this, DiagnosticEventType.MaxAttemptsExceeded)
                {
                    Detail  = "Maximum attempts exceeded (" + _maxAttempts + ")",
                    Message = message,
                    Queue   = QueueName
                }.Build(), cancellationToken);

                var maxAttemptsExceededHandlers = MaximumAttemptsExceeded;
                if (maxAttemptsExceededHandlers != null)
                {
                    await MaximumAttemptsExceeded(this, eventArgs);
                }

                return;
            }

            var acknowledgementFailureHandlers = AcknowledgementFailure;

            if (acknowledgementFailureHandlers != null)
            {
                await AcknowledgementFailure(this, eventArgs);
            }

            await DiagnosticService.EmitAsync(
                new DiagnosticEventBuilder(this, DiagnosticEventType.QueuedMessageRetry)
            {
                Detail  = "Message not acknowledged; retrying in " + _retryDelay,
                Message = message,
                Queue   = QueueName
            }.Build(), cancellationToken);

            ScheduleRetry(queuedMessage, cancellationToken);
        }