コード例 #1
0
            public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
            {
                try
                {
                    var message         = handlingContext.Error.Message;
                    var destination     = message.Headers["ServiceControl.TargetEndpointAddress"];
                    var messageUniqueId = message.Headers["ServiceControl.Retry.UniqueMessageId"];
                    Log.Warn($"Failed to send '{messageUniqueId}' message to '{destination}' for retry. Attempting to revert message status to unresolved so it can be tried again.", handlingContext.Error.Exception);

                    using (var session = store.OpenAsyncSession())
                    {
                        var failedMessage = await session.LoadAsync <FailedMessage>(FailedMessage.MakeDocumentId(messageUniqueId))
                                            .ConfigureAwait(false);

                        if (failedMessage != null)
                        {
                            failedMessage.Status = FailedMessageStatus.Unresolved;
                        }

                        var failedMessageRetry = await session.LoadAsync <FailedMessageRetry>(FailedMessageRetry.MakeDocumentId(messageUniqueId))
                                                 .ConfigureAwait(false);

                        if (failedMessageRetry != null)
                        {
                            session.Delete(failedMessageRetry);
                        }

                        await session.SaveChangesAsync()
                        .ConfigureAwait(false);
                    }

                    string reason;
                    try
                    {
                        reason = handlingContext.Error.Exception.GetBaseException().Message;
                    }
                    catch (Exception)
                    {
                        reason = "Failed to retrieve reason!";
                    }

                    await domainEvents.Raise(new MessagesSubmittedForRetryFailed
                    {
                        Reason          = reason,
                        FailedMessageId = messageUniqueId,
                        Destination     = destination
                    }).ConfigureAwait(false);
                }
                catch (Exception ex)
                {
                    // If something goes wrong here we just ignore, not the end of the world!
                    Log.Error("A failure occurred when trying to handle a retry failure.", ex);
                }
                finally
                {
                    executeOnFailure();
                }

                return(ErrorHandleResult.Handled);
            }
コード例 #2
0
        /// <summary>
        /// Invoked when an error occurs while processing a message.
        /// </summary>
        /// <param name="handlingContext">Error handling context.</param>
        /// <param name="dispatcher">Dispatcher.</param>
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            var message = handlingContext.Error.Message;

            if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries)
            {
                return(ErrorHandleResult.RetryRequired);
            }
            string delayedRetryHeader;

            if (message.Headers.TryGetValue("NServiceBus.Raw.DelayedRetries.Attempt", out delayedRetryHeader))
            {
                var attempt = int.Parse(delayedRetryHeader);
                if (attempt >= delayedRetries)
                {
                    await handlingContext.MoveToErrorQueue(errorQueue).ConfigureAwait(false);

                    return(ErrorHandleResult.Handled);
                }
            }

            message.Headers["NServiceBus.Raw.DelayedRetries.Due"]     = (DateTime.UtcNow + delay).ToString("O");
            message.Headers["NServiceBus.Raw.DelayedRetries.RetryTo"] = handlingContext.FailedQueue;
            var delayedMessage = new OutgoingMessage(message.MessageId, message.Headers, message.Body);
            var operation      = new TransportOperation(delayedMessage, new UnicastAddressTag(delayQueue));
            await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag())
            .ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
コード例 #3
0
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries)
            {
                return(ErrorHandleResult.RetryRequired);
            }

            if (handlingContext.Error.DelayedDeliveriesPerformed >= delayedRetries)
            {
                //More than five times this message triggered throttled mode -> poison
                return(await poisonMessageHandling(handlingContext, dispatcher).ConfigureAwait(false));
            }

            //Move to back of the queue.
            var incomingMessage = handlingContext.Error.Message;
            var message         = new OutgoingMessage(incomingMessage.MessageId, incomingMessage.Headers, incomingMessage.Body);
            var operation       = new TransportOperation(message, new UnicastAddressTag(inputQueue));

            //Only increment the delayed retries count if CB was not armed. That means that at least one message was
            //successfully forwarded in between previous failure of this message and this failure.
            //This prevents prematurely exhausting delayed retries attempts without triggering the throttled mode
            if (!circuitBreaker.IsArmed)
            {
                var newDelayedRetriesHeaderValue = handlingContext.Error.DelayedDeliveriesPerformed + 1;
                incomingMessage.Headers[Headers.DelayedRetries] = newDelayedRetriesHeaderValue.ToString();
            }
            await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag())
            .ConfigureAwait(false);

            //Notify the circuit breaker
            await circuitBreaker.Failure(handlingContext.Error.Exception).ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
コード例 #4
0
 public Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
 {
     if (handlingContext.Error.ImmediateProcessingFailures < immediateRetryCount)
     {
         return(Task.FromResult(ErrorHandleResult.RetryRequired));
     }
     return(handlingContext.MoveToErrorQueue(errorQueue));
 }
コード例 #5
0
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            //Same as recoverability policy in NServiceBusFactory
            if (handlingContext.Error.ImmediateProcessingFailures < 3)
            {
                return(ErrorHandleResult.RetryRequired);
            }

            await importFailuresHandler.Handle(handlingContext.Error)
            .ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
コード例 #6
0
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            //Same as recoverability policy in NServiceBusFactory
            if (handlingContext.Error.ImmediateProcessingFailures < 3)
            {
                return(ErrorHandleResult.RetryRequired);
            }

            await StoreFailedMessageDocument(handlingContext.Error)
            .ConfigureAwait(false);

            await handlingContext.MoveToErrorQueue(handlingContext.FailedQueue, false)
            .ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
コード例 #7
0
        public async Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
        {
            await Task.Delay(1000);

            if (handlingContext.Error.ImmediateProcessingFailures < immediateRetries)
            {
                return(ErrorHandleResult.RetryRequired);
            }

            logger.Error("Error processing a message. Continuing in throttled mode.", handlingContext.Error.Exception);

            //Move to back of the queue.
            var incomingMessage = handlingContext.Error.Message;
            var message         = new OutgoingMessage(incomingMessage.MessageId, incomingMessage.Headers, incomingMessage.Body);
            var operation       = new TransportOperation(message, new UnicastAddressTag(inputQueue));

            await dispatcher.Dispatch(new TransportOperations(operation), handlingContext.Error.TransportTransaction, new ContextBag())
            .ConfigureAwait(false);

            return(ErrorHandleResult.Handled);
        }
コード例 #8
0
 public Task <ErrorHandleResult> OnError(IErrorHandlingPolicyContext handlingContext, IDispatchMessages dispatcher)
 {
     return(Task.FromResult(ErrorHandleResult.Handled));
 }