Esempio n. 1
0
        static Func <ErrorContext, RecoverabilityAction> CreatePolicy(int maxImmediateRetries = 2, int maxDelayedRetries = 2, TimeSpan?delayedRetryDelay = null, HashSet <Type> unrecoverableExceptions = null)
        {
            var failedConfig = new FailedConfig("errorQueue", unrecoverableExceptions ?? new HashSet <Type>());
            var config       = new RecoverabilityConfig(new ImmediateConfig(maxImmediateRetries), new DelayedConfig(maxDelayedRetries, delayedRetryDelay.GetValueOrDefault(TimeSpan.FromSeconds(2))), failedConfig);

            return(context => DefaultRecoverabilityPolicy.Invoke(config, context));
        }
Esempio n. 2
0
        static RecoverabilityAction OrderPlacedPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var errorCategory = ErrorCategory.Unknown;

            if (context.Message.Headers.ContainsKey("NServiceBus.EnclosedMessageTypes"))
            {
                if (context.Message.Headers["NServiceBus.EnclosedMessageTypes"].StartsWith("Messages.Commands.PlaceOrder"))
                {
                    errorCategory = FailPolicy.GetPolicy("Messages.Commands.PlaceOrder").GetCategory(context.Exception);
                }
                else if (context.Message.Headers["NServiceBus.EnclosedMessageTypes"].StartsWith("Messages.Commands.CancelOrder"))
                {
                    errorCategory = FailPolicy.GetPolicy("Messages.Commands.CancelOrder").GetCategory(context.Exception);
                }
            }

            if (errorCategory == ErrorCategory.Persistent)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            else if (errorCategory == ErrorCategory.SemiTransient)
            {
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(60)));
            }

            // invocation of default recoverability policy
            return(DefaultRecoverabilityPolicy.Invoke(config, context));
        }
        private RecoverabilityAction CreateSubjectCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            // In this custom policy, we are electing to move the PoisonedMessages to a different error queue for resolution, so they will use a different error queue to the standard one (so can be monitored easily).
            // You could add whatever logic you liked here to put different messages in different queues.

            return(config.Failed.UnrecoverableExceptionTypes.Count(exType => exType.IsInstanceOfType(context.Exception)) > 0
                ? RecoverabilityAction.MoveToError("customErrorQueue")
                : DefaultRecoverabilityPolicy.Invoke(config, context));
        }
Esempio n. 4
0
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            if (context.Exception is MyBusinessException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }

            return(DefaultRecoverabilityPolicy.Invoke(config, context));
        }
Esempio n. 5
0
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }
            // Override default delivery delay.
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
        }
Esempio n. 6
0
        RecoverabilityAction OnAuditError(RecoverabilityConfig config, ErrorContext errorContext)
        {
            var recoverabilityAction = DefaultRecoverabilityPolicy.Invoke(config, errorContext);

            if (recoverabilityAction is MoveToError)
            {
                importFailuresHandler.Handle(errorContext).GetAwaiter().GetResult();
            }

            return(recoverabilityAction);
        }
Esempio n. 7
0
        public static RecoverabilityAction UserServiceRetryPolicyInvoke(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry))
            {
                return(action);
            }
            if (context.Exception is NullReferenceException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMinutes(3)));
        }
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            // invocation of default recoverability policy
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            // override delayed retry decision for custom exception
            // i.e. MyOtherBusinessException should do fixed backoff of 5 seconds
            if (action is DelayedRetry delayedRetryAction &&
                context.Exception is MyOtherBusinessException)
            {
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
            }

            return(action);
        }
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }
            if (context.Exception is MyBusinessException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            // Override default delivery delay.
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
        }
Esempio n. 10
0
        void Simple(EndpointConfiguration endpointConfiguration, IEndpointInstance endpoint, ILog log)
        {
            #region Callbacks-Recoverability

            endpointConfiguration.Recoverability().CustomPolicy((config, context) =>
            {
                if (context.Exception is InvalidOperationException invalidOperationException &&
                    invalidOperationException.Message.StartsWith("No handlers could be found", StringComparison.OrdinalIgnoreCase))
                {
                    return(RecoverabilityAction.Discard("Callback no longer active"));
                }
                return(DefaultRecoverabilityPolicy.Invoke(config, context));
            });

            #endregion
        }
        static RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var numberOfRetries   = context.DelayedDeliveriesPerformed;
            var exceptionInstance = context.Exception;

            // call the default recoverability of default behavior is desired
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (action is DelayedRetry delayedRetryAction)
            {
                // perform some logic and decide when to do delayed retries
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
            }

            return(action);
        }
        public RecoverabilityAction Invoke(RecoverabilityConfig config, ErrorContext errorContext)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, errorContext);

            if (action is MoveToError)
            {
                if (SendFailedMessagesToErrorQueue)
                {
                    return(action);
                }

                // 7.2 offers a Discard option, but we want to bubble up the exception so it can fail the function invocation.
                throw new Exception("Failed to process message.", errorContext.Exception);
            }

            return(action);
        }
Esempio n. 13
0
 public RecoverabilityAction WebhookRetryPolicy(RecoverabilityConfig config, ErrorContext context)
 {
     if (context.Exception is WebhookExceptionRetryPerPolicy)
     {
         // Check that the number of delayed deliveries does not exceed configurable webhook retry count
         if (context.DelayedDeliveriesPerformed < ConfigHelper.WebhookRetryCount)
         {
             // Set delayed retry internal to that set by the configurable webhook retry internal
             return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(ConfigHelper.WebhookRetryInterval)));
         }
         // If the webhook could not be delivered within the specified number of retry attempts. Log error and send to ErrorQueue
         string errorMsg = $"Failed to send webhook after {context.DelayedDeliveriesPerformed} attempts.";
         Log.Error(errorMsg);
         return(RecoverabilityAction.MoveToError(errorMsg));
     }
     // For all other exceptions, fall back to default policy
     return(DefaultRecoverabilityPolicy.Invoke(config, context));
 }
        public RecoverabilityAction Retry(RecoverabilityConfig recoverabilityConfig, ErrorContext errorContext)
        {
            if (errorContext.Exception is OptimisticConcurrencyException)
            {
                var ttl = errorContext.Message.Headers[
                    ApplicationConfiguration.Instance.GetValue <string>(
                        "ProductService:RetryPolicy:HeaderNames:UpdateStockInProduct")];

                if (Convert.ToInt32(ttl) == 0)
                {
                    return(RecoverabilityAction.MoveToError(recoverabilityConfig.Failed.ErrorQueue));
                }

                //TODO:Kudret--> Beklediğim bir senaryo, bu yüzden immediate olarak retry etsin
                return(RecoverabilityAction.ImmediateRetry());
            }

            return(DefaultRecoverabilityPolicy.Invoke(recoverabilityConfig, errorContext));
        }
Esempio n. 15
0
        public static RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            // If not a retry then continue
            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }

            // Check for concrete exception or business custom exception
            if (context.Exception is InvalidCastException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }

            // Override default delivery delay.
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
        }
Esempio n. 16
0
        public static RecoverabilityAction MyCoronaServiceRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }

            /* if (context.Exception is PatientNotExistExcption)
             * {
             *   return RecoverabilityAction.MoveToError(config.Failed.ErrorQueue);
             * }*/
            if (context.Exception is NullReferenceException)
            {
                return(RecoverabilityAction.Discard("Business operation timed out."));
            }
            // Override default delivery delay.
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMinutes(3)));
        }
        RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            // early decisions and return before custom policy is invoked
            // i.e. MyBusinessException should always go to error
            if (context.Exception is MyBusinessException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }

            // invocation of default recoverability policy
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            // override delayed retry decision for custom exception
            // i.e. MyOtherBusinessException should do fixed backoff of 5 seconds
            if (action is DelayedRetry delayedRetryAction &&
                context.Exception is MyOtherBusinessException)
            {
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5)));
            }

            return(action);
        }
Esempio n. 18
0
        private static RecoverabilityAction SubscriberServiceRetryPolicy(RecoverabilityConfig config, ErrorContext context)
        {
            var action = DefaultRecoverabilityPolicy.Invoke(config, context);

            if (!(action is DelayedRetry delayedRetryAction))
            {
                return(action);
            }
            if (context.Exception is UserNotFoundException)
            {
                return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
            }
            // Override default delivery delay.

            /*          var recoverability = endpointConfiguration.Recoverability();
             *          recoverability.Delayed(
             *              customizations: delayed =>
             *              {
             *                  delayed.NumberOfRetries(3);
             *                  delayed.TimeIncrease(TimeSpan.FromMinutes(3));
             *              });*/
            return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMinutes(3)));
        }
Esempio n. 19
0
        static async Task Main()
        {
            const string endpointName = "HealthMinistry";

            Console.Title = endpointName;

            var endpointConfiguration = new EndpointConfiguration(endpointName);

            endpointConfiguration.EnableInstallers();

            endpointConfiguration.AuditProcessedMessagesTo("audit");

            endpointConfiguration.AuditSagaStateChanges(
                serviceControlQueue: "Particular.Servicecontrol");

            var settings = new JsonSerializerSettings
            {
                Formatting = Formatting.Indented
            };
            var serialization = endpointConfiguration.UseSerialization <NewtonsoftSerializer>();

            serialization.Settings(settings);


            var persistence = endpointConfiguration.UsePersistence <SqlPersistence>();


            var persistenceConnection = ConfigurationManager.ConnectionStrings["persistenceConnection"].ToString();

            var transportConnection = ConfigurationManager.ConnectionStrings["transportConnection"].ToString();

            persistence.SqlDialect <SqlDialect.MsSqlServer>();

            persistence.ConnectionBuilder(
                connectionBuilder: () =>
            {
                return(new SqlConnection(persistenceConnection));
            });


            var outboxSettings = endpointConfiguration.EnableOutbox();

            outboxSettings.KeepDeduplicationDataFor(TimeSpan.FromDays(6));
            outboxSettings.RunDeduplicationDataCleanupEvery(TimeSpan.FromMinutes(15));

            var recoverability = endpointConfiguration.Recoverability();

            recoverability.CustomPolicy(MyCoronaServiceRetryPolicy);

            var transport = endpointConfiguration.UseTransport <RabbitMQTransport>();

            transport.UseConventionalRoutingTopology()
            .ConnectionString(transportConnection);


            var routing = transport.Routing();

            routing.RouteToEndpoint(
                typeof(ISendEmail).Assembly, "HealthMinistry");



            RecoverabilityAction MyCoronaServiceRetryPolicy(RecoverabilityConfig config, ErrorContext context)
            {
                var action = DefaultRecoverabilityPolicy.Invoke(config, context);

                if (!(action is DelayedRetry delayedRetryAction))
                {
                    return(action);
                }
                if (context.Exception is PatientNotExistExcption)
                {
                    return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue));
                }
                // Override default delivery delay.
                return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMinutes(3)));
            }

            var conventions = endpointConfiguration.Conventions();

            conventions.DefiningCommandsAs(type => type.Namespace == "Messages.Commands");
            conventions.DefiningEventsAs(type => type.Namespace == "Messages.Events");

            var endpointInstance = await Endpoint.Start(endpointConfiguration)
                                   .ConfigureAwait(false);

            Console.WriteLine("Press Enter to exit.");
            Console.ReadLine();

            await endpointInstance.Stop()
            .ConfigureAwait(false);
        }