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)); }
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)); }
RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context) { if (context.Exception is MyBusinessException) { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); } return(DefaultRecoverabilityPolicy.Invoke(config, context)); }
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))); }
RecoverabilityAction OnAuditError(RecoverabilityConfig config, ErrorContext errorContext) { var recoverabilityAction = DefaultRecoverabilityPolicy.Invoke(config, errorContext); if (recoverabilityAction is MoveToError) { importFailuresHandler.Handle(errorContext).GetAwaiter().GetResult(); } return(recoverabilityAction); }
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))); }
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); }
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)); }
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))); }
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); }
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))); }
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); }