/// <summary>
 /// Constructs the step, using the given transport and settings
 /// </summary>
 public SimpleRetryStrategyStep(SimpleRetryStrategySettings simpleRetryStrategySettings, IRebusLoggerFactory rebusLoggerFactory, IErrorTracker errorTracker, IErrorHandler errorHandler, CancellationToken cancellationToken)
 {
     _simpleRetryStrategySettings = simpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(simpleRetryStrategySettings));
     _errorTracker      = errorTracker ?? throw new ArgumentNullException(nameof(errorTracker));
     _errorHandler      = errorHandler ?? throw new ArgumentNullException(nameof(errorHandler));
     _logger            = rebusLoggerFactory?.GetLogger <SimpleRetryStrategyStep>() ?? throw new ArgumentNullException(nameof(rebusLoggerFactory));
     _cancellationToken = cancellationToken;
 }
Exemple #2
0
 /// <summary>
 /// Constructs the retry strategy with the given settings, creating an error queue with the configured name if necessary
 /// </summary>
 public ArkRetryStrategy(SimpleRetryStrategySettings simpleRetryStrategySettings, IRebusLoggerFactory rebusLoggerFactory, IErrorTracker errorTracker, IErrorHandler errorHandler, IFailFastChecker failFastChecker, CancellationToken cancellationToken)
 {
     _simpleRetryStrategySettings = simpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(simpleRetryStrategySettings));
     _rebusLoggerFactory          = rebusLoggerFactory ?? throw new ArgumentNullException(nameof(rebusLoggerFactory));
     _errorTracker      = errorTracker ?? throw new ArgumentNullException(nameof(errorTracker));
     _errorHandler      = errorHandler ?? throw new ArgumentNullException(nameof(errorHandler));
     _failFastChecker   = failFastChecker;
     _cancellationToken = cancellationToken;
 }
    protected override void SetUp()
    {
        _network.Reset();

        _simpleRetryStrategySettings = new SimpleRetryStrategySettings();
        _transport = new InMemTransport(_network, "whatever");
        _handler   = new PoisonQueueErrorHandler(_simpleRetryStrategySettings, _transport, new ConsoleLoggerFactory(false));
        _handler.Initialize();
    }
 public RetryStrategyStep(RetryStrategySettings retryStrategySettings,
                          IErrorTracker errorTracker,
                          IErrorHandler errorHandler)
 {
     _retryStrategySettings       = retryStrategySettings ?? throw new ArgumentNullException(nameof(retryStrategySettings));
     _simpleRetryStrategySettings = retryStrategySettings.SimpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(retryStrategySettings.SimpleRetryStrategySettings));
     _errorTracker = errorTracker ?? throw new ArgumentNullException(nameof(errorTracker));
     _errorHandler = errorHandler ?? throw new ArgumentNullException(nameof(errorHandler));
 }
Exemple #5
0
 /// <summary>
 /// Creates the error handler
 /// </summary>
 public PoisonQueueErrorHandler(SimpleRetryStrategySettings simpleRetryStrategySettings, ITransport transport, IRebusLoggerFactory rebusLoggerFactory)
 {
     if (simpleRetryStrategySettings == null)
     {
         throw new ArgumentNullException(nameof(simpleRetryStrategySettings));
     }
     if (transport == null)
     {
         throw new ArgumentNullException(nameof(transport));
     }
     if (rebusLoggerFactory == null)
     {
         throw new ArgumentNullException(nameof(rebusLoggerFactory));
     }
     _simpleRetryStrategySettings = simpleRetryStrategySettings;
     _transport = transport;
     _log       = rebusLoggerFactory.GetCurrentClassLogger();
 }
Exemple #6
0
    /// <summary>
    /// Configures the simple retry strategy, using the specified error queue address and number of delivery attempts
    /// </summary>
    /// <param name="optionsConfigurer">(extension method target)</param>
    /// <param name="errorQueueAddress">Specifies the name of the error queue</param>
    /// <param name="maxDeliveryAttempts">Specifies how many delivery attempts should be made before forwarding a failed message to the error queue</param>
    /// <param name="secondLevelRetriesEnabled">Specifies whether second level retries should be enabled - when enabled, the message will be dispatched wrapped in an <see cref="IFailed{TMessage}"/> after the first <paramref name="maxDeliveryAttempts"/> delivery attempts, allowing a different handler to handle the message. Dispatch of the <see cref="IFailed{TMessage}"/> is subject to the same <paramref name="maxDeliveryAttempts"/> delivery attempts</param>
    /// <param name="errorDetailsHeaderMaxLength">Specifies a MAX length of the error details to be enclosed as the <see cref="Headers.ErrorDetails"/> header. As the enclosed error details can sometimes become very long (especially when using many delivery attempts), depending on the transport's capabilities it might sometimes be necessary to truncate the error details</param>
    /// <param name="errorTrackingMaxAgeMinutes">Specifies the max age of in-mem error trackings, for tracked messages that have not had any activity registered on them.</param>
    public static void SimpleRetryStrategy(this OptionsConfigurer optionsConfigurer,
                                           string errorQueueAddress        = SimpleRetryStrategySettings.DefaultErrorQueueName,
                                           int maxDeliveryAttempts         = SimpleRetryStrategySettings.DefaultNumberOfDeliveryAttempts,
                                           bool secondLevelRetriesEnabled  = false,
                                           int errorDetailsHeaderMaxLength = int.MaxValue,
                                           int errorTrackingMaxAgeMinutes  = SimpleRetryStrategySettings.DefaultErrorTrackingMaxAgeMinutes
                                           )
    {
        if (optionsConfigurer == null)
        {
            throw new ArgumentNullException(nameof(optionsConfigurer));
        }

        optionsConfigurer.Register(c =>
        {
            var settings = new SimpleRetryStrategySettings(
                errorQueueAddress,
                maxDeliveryAttempts,
                secondLevelRetriesEnabled,
                errorDetailsHeaderMaxLength,
                errorTrackingMaxAgeMinutes
                );

            return(settings);
        });

        if (secondLevelRetriesEnabled)
        {
            optionsConfigurer.Decorate <IPipeline>(c =>
            {
                var pipeline     = c.Get <IPipeline>();
                var errorTracker = c.Get <IErrorTracker>();

                var incomingStep = new FailedMessageWrapperStep(errorTracker);
                var outgoingStep = new VerifyCannotSendFailedMessageWrapperStep();

                return(new PipelineStepInjector(pipeline)
                       .OnReceive(incomingStep, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep))
                       .OnSend(outgoingStep, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep)));
            });
        }
    }
Exemple #7
0
        /// <summary>
        /// Constructs the in-mem error tracker with the configured number of delivery attempts as the MAX
        /// </summary>
        public InMemErrorTracker(SimpleRetryStrategySettings simpleRetryStrategySettings, IRebusLoggerFactory rebusLoggerFactory, IAsyncTaskFactory asyncTaskFactory, ITransport transport)
        {
            if (rebusLoggerFactory == null)
            {
                throw new ArgumentNullException(nameof(rebusLoggerFactory));
            }
            if (asyncTaskFactory == null)
            {
                throw new ArgumentNullException(nameof(asyncTaskFactory));
            }

            _simpleRetryStrategySettings = simpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(simpleRetryStrategySettings));
            _transport = transport ?? throw new ArgumentNullException(nameof(transport));

            _log = rebusLoggerFactory.GetLogger <InMemErrorTracker>();

            _cleanupOldTrackedErrorsTask = asyncTaskFactory.Create(
                BackgroundTaskName,
                CleanupOldTrackedErrors,
                intervalSeconds: 10
                );
        }
Exemple #8
0
 /// <summary>
 /// Creates the error handler
 /// </summary>
 public PoisonQueueErrorHandler(SimpleRetryStrategySettings simpleRetryStrategySettings, ITransport transport, IRebusLoggerFactory rebusLoggerFactory)
 {
     _log       = rebusLoggerFactory?.GetLogger <PoisonQueueErrorHandler>() ?? throw new ArgumentNullException(nameof(rebusLoggerFactory));
     _transport = transport ?? throw new ArgumentNullException(nameof(transport));
     _simpleRetryStrategySettings = simpleRetryStrategySettings ?? throw new ArgumentNullException(nameof(simpleRetryStrategySettings));
 }
 public CommandsErrorHandler(IServiceProvider serviceProvider, ISerializer serializer, SimpleRetryStrategySettings simpleRetryStrategySettings, ITransport transport, IRebusLoggerFactory rebusLoggerFactory)
 {
     _serviceProvider = serviceProvider;
     _serializer      = serializer;
     _innerHandler    = new PoisonQueueErrorHandler(simpleRetryStrategySettings, transport, rebusLoggerFactory);
 }
Exemple #10
0
        /// <summary>
        /// Configures the simple retry strategy, using the specified error queue address and number of delivery attempts
        /// </summary>
        /// <param name="optionsConfigurer">(extension method target)</param>
        /// <param name="errorQueueAddress">Specifies the name of the error queue</param>
        /// <param name="maxDeliveryAttempts">Specifies how many delivery attempts should be made before forwarding a failed message to the error queue</param>
        /// <param name="secondLevelRetriesEnabled">Specifies whether second level retries should be enabled - when enabled, the message will be dispatched wrapped in an <see cref="IFailed{TMessage}"/> after the first <paramref name="maxDeliveryAttempts"/> delivery attempts, allowing a different handler to handle the message. Dispatch of the <see cref="IFailed{TMessage}"/> is subject to the same <paramref name="maxDeliveryAttempts"/> delivery attempts</param>
        /// <param name="errorDetailsHeaderMaxLength">Specifies a MAX length of the error details to be enclosed as the <see cref="Headers.ErrorDetails"/> header. As the enclosed error details can sometimes become very long (especially when using many delivery attempts), depending on the transport's capabilities it might sometimes be necessary to truncate the error details</param>
        /// <param name="errorTrackingMaxAgeMinutes">Specifies the max age of in-mem error trackings, for tracked messages that have not had any activity registered on them.</param>
        public static void ArkRetryStrategy(this OptionsConfigurer optionsConfigurer,
                                            string errorQueueAddress        = SimpleRetryStrategySettings.DefaultErrorQueueName,
                                            int maxDeliveryAttempts         = SimpleRetryStrategySettings.DefaultNumberOfDeliveryAttempts,
                                            bool secondLevelRetriesEnabled  = false,
                                            int errorDetailsHeaderMaxLength = int.MaxValue,
                                            int errorTrackingMaxAgeMinutes  = SimpleRetryStrategySettings.DefaultErrorTrackingMaxAgeMinutes
                                            )
        {
            if (optionsConfigurer == null)
            {
                throw new ArgumentNullException(nameof(optionsConfigurer));
            }

            optionsConfigurer.Register(c =>
            {
                var settings = new SimpleRetryStrategySettings(
                    errorQueueAddress,
                    maxDeliveryAttempts,
                    secondLevelRetriesEnabled,
                    errorDetailsHeaderMaxLength,
                    errorTrackingMaxAgeMinutes
                    );

                return(settings);
            });

            optionsConfigurer.Register <IRetryStrategy>(c =>
            {
                var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>();
                var rebusLoggerFactory          = c.Get <IRebusLoggerFactory>();
                var errorTracker      = c.Get <IErrorTracker>();
                var errorHandler      = c.Get <IErrorHandler>();
                var failFastChecker   = c.Get <IFailFastChecker>();
                var cancellationToken = c.Get <CancellationToken>();
                return(new ArkRetryStrategy(simpleRetryStrategySettings, rebusLoggerFactory, errorTracker, errorHandler, failFastChecker, cancellationToken));
            });

            optionsConfigurer.Register <IErrorTracker>(c =>
            {
                return(new InMemErrorTracker(
                           c.Get <SimpleRetryStrategySettings>(),
                           c.Get <IRebusLoggerFactory>(),
                           c.Get <IAsyncTaskFactory>(),
                           c.Get <ITransport>(),
                           c.Get <IRebusTime>()
                           ));
            });

            if (secondLevelRetriesEnabled)
            {
                optionsConfigurer.Decorate <IPipeline>(c =>
                {
                    var pipeline     = c.Get <IPipeline>();
                    var errorTracker = c.Get <IErrorTracker>();

                    var incomingStep = new FailedMessageWrapperStep(errorTracker);
                    var outgoingStep = new VerifyCannotSendFailedMessageWrapperStep();

                    return(new PipelineStepInjector(pipeline)
                           .OnReceive(incomingStep, PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep))
                           .OnSend(outgoingStep, PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep)));
                });
            }
        }
Exemple #11
0
 public RetryStrategySettings(SimpleRetryStrategySettings simple, bool unErrorLogBlockWait = false)
 {
     SimpleRetryStrategySettings = simple ?? throw new ArgumentNullException(nameof(simple));
     UnErrorLogBlockWait         = unErrorLogBlockWait;
 }
 public FakeErrorTracker(SimpleRetryStrategySettings options)
 {
     Options = options;
 }