Provides information about the recoverability configuration.
        public void Initialize(ReceiveComponent.Configuration receiveConfiguration, HostingComponent.Configuration hostingConfiguration, TransportSeam transportSeam)
        {
            if (receiveConfiguration.IsSendOnlyEndpoint)
            {
                //Message recoverability is only relevant for endpoints receiving messages.
                return;
            }

            hostInformation    = hostingConfiguration.HostInformation;
            this.transportSeam = transportSeam;

            transactionsOn = transportSeam.TransportDefinition.TransportTransactionMode != TransportTransactionMode.None;

            var errorQueue = settings.ErrorQueueAddress();

            transportSeam.QueueBindings.BindSending(errorQueue);

            var immediateRetryConfig = GetImmediateRetryConfig();

            var delayedRetryConfig = GetDelayedRetryConfig();

            var failedConfig = new FailedConfig(errorQueue, settings.UnrecoverableExceptions());

            recoverabilityConfig = new RecoverabilityConfig(immediateRetryConfig, delayedRetryConfig, failedConfig);

            hostingConfiguration.AddStartupDiagnosticsSection("Recoverability", new
            {
                ImmediateRetries           = recoverabilityConfig.Immediate.MaxNumberOfRetries,
                DelayedRetries             = recoverabilityConfig.Delayed.MaxNumberOfRetries,
                DelayedRetriesTimeIncrease = recoverabilityConfig.Delayed.TimeIncrease.ToString("g"),
                recoverabilityConfig.Failed.ErrorQueue,
                UnrecoverableExceptions = recoverabilityConfig.Failed.UnrecoverableExceptionTypes.Select(t => t.FullName).ToArray()
            });
        }
Example #2
0
        /// <summary>
        /// Invokes the default recovery policy.
        /// </summary>
        /// <param name="config">The recoverability configuration.</param>
        /// <param name="errorContext">The error context.</param>
        /// <returns>The recoverability action.</returns>
        public static RecoverabilityAction Invoke(RecoverabilityConfig config, ErrorContext errorContext)
        {
            Guard.AgainstNull(nameof(errorContext), errorContext);
            Guard.AgainstNull(nameof(config), config);
            // ReSharper disable once LoopCanBeConvertedToQuery
            foreach (var unrecoverableExceptionType in config.Failed.UnrecoverableExceptionTypes)
            {
                if (unrecoverableExceptionType.IsInstanceOfType(errorContext.Exception))
                {
                    return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
                }
            }

            if (errorContext.ImmediateProcessingFailures <= config.Immediate.MaxNumberOfRetries)
            {
                return(RecoverabilityAction.ImmediateRetry());
            }

            TimeSpan delay;

            if (TryGetDelay(errorContext.Message, errorContext.DelayedDeliveriesPerformed, config.Delayed, out delay))
            {
                return(RecoverabilityAction.DelayedRetry(delay));
            }

            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        }
Example #3
0
        public void Initialize(ReceiveConfiguration receiveConfiguration)
        {
            if (settings.GetOrDefault <bool>("Endpoint.SendOnly"))
            {
                //Message recoverability is only relevant for endpoints receiving messages.
                return;
            }

            transactionsOn = receiveConfiguration.TransactionMode != TransportTransactionMode.None;

            var errorQueue = settings.ErrorQueueAddress();

            settings.Get <QueueBindings>().BindSending(errorQueue);

            var delayedRetryConfig = GetDelayedRetryConfig();

            var immediateRetryConfig = GetImmediateRetryConfig();

            var failedConfig = new FailedConfig(errorQueue, settings.UnrecoverableExceptions());

            recoverabilityConfig = new RecoverabilityConfig(immediateRetryConfig, delayedRetryConfig, failedConfig);

            settings.AddStartupDiagnosticsSection("Recoverability", new
            {
                ImmediateRetries           = recoverabilityConfig.Immediate.MaxNumberOfRetries,
                DelayedRetries             = recoverabilityConfig.Delayed.MaxNumberOfRetries,
                DelayedRetriesTimeIncrease = recoverabilityConfig.Delayed.TimeIncrease.ToString("g"),
                recoverabilityConfig.Failed.ErrorQueue,
                UnrecoverableExceptions = recoverabilityConfig.Failed.UnrecoverableExceptionTypes.Select(t => t.FullName).ToArray()
            });

            WireUpLegacyNotifications();
        }
 public RecoverabilityExecutorFactory(Func<RecoverabilityConfig, ErrorContext, RecoverabilityAction> defaultRecoverabilityPolicy, RecoverabilityConfig configuration, Func<string, DelayedRetryExecutor> delayedRetryExecutorFactory,
     Func<string, MoveToErrorsExecutor> moveToErrorsExecutorFactory, bool immediateRetriesAvailable, bool delayedRetriesAvailable)
 {
     this.configuration = configuration;
     this.defaultRecoverabilityPolicy = defaultRecoverabilityPolicy;
     this.delayedRetryExecutorFactory = delayedRetryExecutorFactory;
     this.moveToErrorsExecutorFactory = moveToErrorsExecutorFactory;
     this.immediateRetriesAvailable = immediateRetriesAvailable;
     this.delayedRetriesAvailable = delayedRetriesAvailable;
 }
        public RecoverabilityExecutor(bool raiseRecoverabilityNotifications, bool immediateRetriesAvailable, bool delayedRetriesAvailable, Func<RecoverabilityConfig, ErrorContext, RecoverabilityAction> recoverabilityPolicy, RecoverabilityConfig configuration, IEventAggregator eventAggregator, DelayedRetryExecutor delayedRetryExecutor, MoveToErrorsExecutor moveToErrorsExecutor)
        {
            this.configuration = configuration;
            this.recoverabilityPolicy = recoverabilityPolicy;
            this.eventAggregator = eventAggregator;
            this.delayedRetryExecutor = delayedRetryExecutor;
            this.moveToErrorsExecutor = moveToErrorsExecutor;
            this.immediateRetriesAvailable = immediateRetriesAvailable;
            this.delayedRetriesAvailable = delayedRetriesAvailable;

            raiseNotifications = raiseRecoverabilityNotifications;
        }
 public RecoverabilityExecutorFactory(
     Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> defaultRecoverabilityPolicy,
     RecoverabilityConfig configuration,
     Func <string, DelayedRetryExecutor> delayedRetryExecutorFactory,
     Func <string, MoveToErrorsExecutor> moveToErrorsExecutorFactory,
     bool immediateRetriesAvailable,
     bool delayedRetriesAvailable,
     INotificationSubscriptions <MessageToBeRetried> messageRetryNotification,
     INotificationSubscriptions <MessageFaulted> messageFaultedNotification)
 {
     this.configuration = configuration;
     this.defaultRecoverabilityPolicy = defaultRecoverabilityPolicy;
     this.delayedRetryExecutorFactory = delayedRetryExecutorFactory;
     this.moveToErrorsExecutorFactory = moveToErrorsExecutorFactory;
     this.immediateRetriesAvailable   = immediateRetriesAvailable;
     this.delayedRetriesAvailable     = delayedRetriesAvailable;
     this.messageRetryNotification    = messageRetryNotification;
     this.messageFaultedNotification  = messageFaultedNotification;
 }
        /// <summary>
        /// Invokes the default recovery policy.
        /// </summary>
        /// <param name="config">The recoverability configuration.</param>
        /// <param name="errorContext">The error context.</param>
        /// <returns>The recoverability action.</returns>
        public static RecoverabilityAction Invoke(RecoverabilityConfig config, ErrorContext errorContext)
        {
            if (errorContext.Exception is MessageDeserializationException)
            {
                return RecoverabilityAction.MoveToError(config.Failed.ErrorQueue);
            }

            if (errorContext.ImmediateProcessingFailures <= config.Immediate.MaxNumberOfRetries)
            {
                return RecoverabilityAction.ImmediateRetry();
            }

            TimeSpan delay;
            if (TryGetDelay(errorContext.Message, errorContext.DelayedDeliveriesPerformed, config.Delayed, out delay))
            {
                return RecoverabilityAction.DelayedRetry(delay);
            }

            return RecoverabilityAction.MoveToError(config.Failed.ErrorQueue);
        }
        /// <summary>
        /// Invokes the default recovery policy.
        /// </summary>
        /// <param name="config">The recoverability configuration.</param>
        /// <param name="errorContext">The error context.</param>
        /// <returns>The recoverability action.</returns>
        public static RecoverabilityAction Invoke(RecoverabilityConfig config, ErrorContext errorContext)
        {
            if (errorContext.Exception is MessageDeserializationException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }

            if (errorContext.ImmediateProcessingFailures <= config.Immediate.MaxNumberOfRetries)
            {
                return(RecoverabilityAction.ImmediateRetry());
            }

            TimeSpan delay;

            if (TryGetDelay(errorContext.Message, errorContext.DelayedDeliveriesPerformed, config.Delayed, out delay))
            {
                return(RecoverabilityAction.DelayedRetry(delay));
            }

            return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
        }
Example #9
0
        public RecoverabilityExecutor(
            bool raiseRecoverabilityNotifications,
            bool immediateRetriesAvailable,
            bool delayedRetriesAvailable,
            Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> recoverabilityPolicy,
            RecoverabilityConfig configuration,
            DelayedRetryExecutor delayedRetryExecutor,
            MoveToErrorsExecutor moveToErrorsExecutor,
            INotificationSubscriptions <MessageToBeRetried> messageRetryNotification,
            INotificationSubscriptions <MessageFaulted> messageFaultedNotification)
        {
            this.configuration              = configuration;
            this.recoverabilityPolicy       = recoverabilityPolicy;
            this.delayedRetryExecutor       = delayedRetryExecutor;
            this.moveToErrorsExecutor       = moveToErrorsExecutor;
            this.messageRetryNotification   = messageRetryNotification;
            this.messageFaultedNotification = messageFaultedNotification;
            this.immediateRetriesAvailable  = immediateRetriesAvailable;
            this.delayedRetriesAvailable    = delayedRetriesAvailable;

            raiseNotifications = raiseRecoverabilityNotifications;
        }
Example #10
0
        public RecoverabilityExecutor(bool raiseRecoverabilityNotifications, bool immediateRetriesAvailable, bool delayedRetriesAvailable, Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> recoverabilityPolicy, RecoverabilityConfig configuration, IEventAggregator eventAggregator, DelayedRetryExecutor delayedRetryExecutor, MoveToErrorsExecutor moveToErrorsExecutor)
        {
            this.configuration             = configuration;
            this.recoverabilityPolicy      = recoverabilityPolicy;
            this.eventAggregator           = eventAggregator;
            this.delayedRetryExecutor      = delayedRetryExecutor;
            this.moveToErrorsExecutor      = moveToErrorsExecutor;
            this.immediateRetriesAvailable = immediateRetriesAvailable;
            this.delayedRetriesAvailable   = delayedRetriesAvailable;

            raiseNotifications = raiseRecoverabilityNotifications;
        }
Example #11
0
        protected internal override void Setup(FeatureConfigurationContext context)
        {
            var errorQueue = context.Settings.ErrorQueueAddress();

            context.Settings.Get <QueueBindings>().BindSending(errorQueue);

            var transactionsOn          = context.Receiving.TransactionMode != TransportTransactionMode.None;
            var delayedRetryConfig      = GetDelayedRetryConfig(context.Settings, transactionsOn);
            var delayedRetriesAvailable = transactionsOn &&
                                          (context.Settings.DoesTransportSupportConstraint <DelayedDeliveryConstraint>() || context.Settings.Get <TimeoutManagerAddressConfiguration>().TransportAddress != null);


            var immediateRetryConfig      = GetImmediateRetryConfig(context.Settings, transactionsOn);
            var immediateRetriesAvailable = transactionsOn;

            var failedConfig = new FailedConfig(errorQueue, context.Settings.UnrecoverableExceptions());

            var recoverabilityConfig = new RecoverabilityConfig(immediateRetryConfig, delayedRetryConfig, failedConfig);

            context.Settings.AddStartupDiagnosticsSection("Recoverability", new
            {
                ImmediateRetries           = recoverabilityConfig.Immediate.MaxNumberOfRetries,
                DelayedRetries             = recoverabilityConfig.Delayed.MaxNumberOfRetries,
                DelayedRetriesTimeIncrease = recoverabilityConfig.Delayed.TimeIncrease.ToString("g"),
                recoverabilityConfig.Failed.ErrorQueue,
                UnrecoverableExceptions = recoverabilityConfig.Failed.UnrecoverableExceptionTypes.Select(t => t.FullName).ToArray()
            });

            context.Container.ConfigureComponent(b =>
            {
                Func <string, MoveToErrorsExecutor> moveToErrorsExecutorFactory = localAddress =>
                {
                    var hostInfo            = b.Build <HostInformation>();
                    var staticFaultMetadata = new Dictionary <string, string>
                    {
                        { FaultsHeaderKeys.FailedQ, localAddress },
                        { Headers.ProcessingMachine, RuntimeEnvironment.MachineName },
                        { Headers.ProcessingEndpoint, context.Settings.EndpointName() },
                        { Headers.HostId, hostInfo.HostId.ToString("N") },
                        { Headers.HostDisplayName, hostInfo.DisplayName }
                    };

                    var headerCustomizations = context.Settings.Get <Action <Dictionary <string, string> > >(FaultHeaderCustomization);

                    return(new MoveToErrorsExecutor(b.Build <IDispatchMessages>(), staticFaultMetadata, headerCustomizations));
                };

                Func <string, DelayedRetryExecutor> delayedRetryExecutorFactory = localAddress =>
                {
                    if (delayedRetriesAvailable)
                    {
                        return(new DelayedRetryExecutor(
                                   localAddress,
                                   b.Build <IDispatchMessages>(),
                                   context.Settings.DoesTransportSupportConstraint <DelayedDeliveryConstraint>()
                                ? null
                                : context.Settings.Get <TimeoutManagerAddressConfiguration>().TransportAddress));
                    }

                    return(null);
                };

                if (!context.Settings.TryGet(PolicyOverride, out Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> policy))
                {
                    policy = DefaultRecoverabilityPolicy.Invoke;
                }

                return(new RecoverabilityExecutorFactory(
                           policy,
                           recoverabilityConfig,
                           delayedRetryExecutorFactory,
                           moveToErrorsExecutorFactory,
                           immediateRetriesAvailable,
                           delayedRetriesAvailable));
            }, DependencyLifecycle.SingleInstance);

            RaiseLegacyNotifications(context);
        }
Example #12
0
 public RecoverabilityExecutorFactory(Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> defaultRecoverabilityPolicy, RecoverabilityConfig configuration, Func <string, DelayedRetryExecutor> delayedRetryExecutorFactory,
                                      Func <string, MoveToErrorsExecutor> moveToErrorsExecutorFactory, bool immediateRetriesAvailable, bool delayedRetriesAvailable)
 {
     this.configuration = configuration;
     this.defaultRecoverabilityPolicy = defaultRecoverabilityPolicy;
     this.delayedRetryExecutorFactory = delayedRetryExecutorFactory;
     this.moveToErrorsExecutorFactory = moveToErrorsExecutorFactory;
     this.immediateRetriesAvailable   = immediateRetriesAvailable;
     this.delayedRetriesAvailable     = delayedRetriesAvailable;
 }