public static Func <RecoverabilityConfig, ErrorContext, RecoverabilityAction> AlwaysMoveToErrors(string errorQueueAddress = "errorQueue") { return(new RetryPolicy(new[] { RecoverabilityAction.MoveToError(errorQueueAddress) }).Invoke); }
RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context) { // early decisions and return before custom policy is invoked // i.e. all unrecoverable exceptions should always go to customized error queue foreach (var exceptionType in config.Failed.UnrecoverableExceptionTypes) { if (exceptionType.IsInstanceOfType(context.Exception)) { return(RecoverabilityAction.MoveToError("customErrorQueue")); } } // If it does not make sense to have this message around anymore // it can be discarded with a reason. if (context.Exception is MyBusinessTimedOutException) { return(RecoverabilityAction.Discard("Business operation timed out.")); } // override delayed retry decision for custom exception // i.e. MyOtherBusinessException should do fixed backoff of 5 seconds if (context.Exception is MyOtherBusinessException && context.DelayedDeliveriesPerformed < config.Delayed.MaxNumberOfRetries) { return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5))); } // in all other cases No Immediate or Delayed Retries, go to default error queue return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }
static async Task <ValidationException> Send(object message, [CallerMemberName] string key = null) { var configuration = new EndpointConfiguration("DataAnnotationsIncoming" + key); configuration.UseTransport <LearningTransport>(); configuration.PurgeOnStartup(true); configuration.DisableFeature <TimeoutManager>(); var resetEvent = new ManualResetEvent(false); configuration.RegisterComponents(components => components.RegisterSingleton(resetEvent)); ValidationException exception = null; var recoverability = configuration.Recoverability(); recoverability.CustomPolicy( (config, context) => { exception = (ValidationException)context.Exception; resetEvent.Set(); return(RecoverabilityAction.MoveToError("error")); }); configuration.UseDataAnnotationsValidation(outgoing: false); var endpoint = await Endpoint.Start(configuration); await endpoint.SendLocal(message); if (!resetEvent.WaitOne(TimeSpan.FromSeconds(2))) { throw new Exception("No Set received."); } return(exception); }
protected override void Setup(FeatureConfigurationContext context) { #region DrainTempQueueSatellite var settings = context.Settings; var qualifiedAddress = settings.LogicalAddress() .CreateQualifiedAddress("New"); var tempQueue = settings.GetTransportAddress(qualifiedAddress); var mainQueue = settings.LocalAddress(); context.AddSatelliteReceiver( name: "DrainTempQueueSatellite", transportAddress: tempQueue, runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1), recoverabilityPolicy: (config, errorContext) => { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }, onMessage: (builder, messageContext) => { var messageDispatcher = builder.Build <IDispatchMessages>(); var outgoingHeaders = messageContext.Headers; var outgoingMessage = new OutgoingMessage(messageContext.MessageId, outgoingHeaders, messageContext.Body); var outgoingOperation = new TransportOperation(outgoingMessage, new UnicastAddressTag(mainQueue)); Console.WriteLine($"Moving message from {tempQueue} to {mainQueue}"); var transportOperations = new TransportOperations(outgoingOperation); return(messageDispatcher.Dispatch(transportOperations, messageContext.TransportTransaction, messageContext.Context)); }); #endregion }
private static RecoverabilityAction CustomerExceptionPolicy(RecoverabilityConfig config, ErrorContext context) { var unrecover = context.Exception is UnrecoverableException; var customer = context.Exception is CustomerException; var immediateIdx = context.ImmediateProcessingFailures; var immediateMax = config.Immediate.MaxNumberOfRetries; var delayIdx = context.DelayedDeliveriesPerformed; var delayMax = config.Delayed.MaxNumberOfRetries; if (!unrecover && immediateIdx < immediateMax) { Console.WriteLine($"DelayedRetry {delayIdx}, ImmediateRetry {immediateIdx}"); return(RecoverabilityAction.ImmediateRetry()); } if (!unrecover && immediateIdx == immediateMax && delayIdx < delayMax) { Console.WriteLine($"DelayedRetry {delayIdx}"); return(RecoverabilityAction.DelayedRetry(config.Delayed.TimeIncrease)); } if (customer && delayIdx == delayMax) { Console.WriteLine("Alert customer exception"); } return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }
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)); }
public RetryEndpoint() { EndpointSetup <DefaultServer>((configure, context) => { configure.Recoverability() .CustomPolicy((cfg, errorContext) => RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue)); }); }
RecoverabilityAction RetryPolicy(RecoverabilityConfig config, ErrorContext context) { if (context.DelayedDeliveriesPerformed == 0) { return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMilliseconds(10))); } return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }
RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context) { if (context.Exception is MyBusinessException) { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); } return(DefaultRecoverabilityPolicy.Invoke(config, context)); }
public void UseNServiceBusPoisonMessageHandling(string errorQueue) { endpointConfiguration.Recoverability().CustomPolicy((c, e) => { return(RecoverabilityAction.MoveToError(errorQueue)); }); moveFailedMessagesToError = true; }
static RecoverabilityAction RecoverabilityPolicy(RecoverabilityConfig config, ErrorContext errorContext) { if (errorContext.ImmediateProcessingFailures <= MaxNumberOfImmediateRetries) { return(RecoverabilityAction.ImmediateRetry()); } return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }
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)); }
public EndpointWithFailingHandler() { EndpointSetup <DefaultServer>((config, context) => { config.Recoverability().CustomPolicy((c, ec) => RecoverabilityAction.MoveToError(Conventions.EndpointNamingConvention(typeof(ErrorSpy)))); config.SendFailedMessagesTo("error"); }); }
public RetryEndpoint() { EndpointSetup <DefaultServer>((configure, context) => { var scenarioContext = (Context)context.ScenarioContext; configure.EnableFeature <TimeoutManager>(); configure.Recoverability() .CustomPolicy((cfg, errorContext) => RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue)); configure.Notifications.Errors.MessageSentToErrorQueue += (sender, message) => { scenarioContext.MessageSentToErrorQueue = true; }; }); }
public static RecoverabilityAction Invoke(ErrorContext errorContext, Func <IncomingMessage, Exception, int, TimeSpan> retryPolicy, RecoverabilityConfig config) { var currentRetry = errorContext.DelayedDeliveriesPerformed + 1; var timeIncrease = retryPolicy(errorContext.Message, errorContext.Exception, currentRetry); if (timeIncrease <= TimeSpan.MinValue) { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); } return(RecoverabilityAction.DelayedRetry(timeIncrease)); }
protected override void Setup(FeatureConfigurationContext context) { context.AddSatelliteReceiver( name: "CustomSatellite", transportAddress: "targetQueue", runtimeSettings: PushRuntimeSettings.Default, recoverabilityPolicy: (config, errorContext) => { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }, onMessage: OnMessage); }
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) { 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))); }
public void MoveToError(FeatureConfigurationContext context) { #region SatelliteRecoverability-ErrorQueue context.AddSatelliteReceiver( name: "CustomSatellite", transportAddress: "targetQueue", requiredTransportTransactionMode: TransportTransactionMode.TransactionScope, runtimeSettings: PushRuntimeSettings.Default, recoverabilityPolicy: (config, errorContext) => { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }, onMessage: OnMessage); #endregion }
public Endpoint() { EndpointSetup <DefaultServer>((config, context) => { var testContext = (Context)context.ScenarioContext; config.Recoverability() .Immediate(immediate => immediate.NumberOfRetries(MaxImmediateRetries)) .Delayed(delayed => delayed.NumberOfRetries(MaxDelayedRetries).TimeIncrease(DelayedRetryDelayIncrease)) .CustomPolicy((cfg, errorContext) => { testContext.Configuration = cfg; return(RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue)); }); }); }
protected override void Setup(FeatureConfigurationContext context) { var satelliteLogicalAddress = context.Settings.LogicalAddress().CreateQualifiedAddress("MySatellite"); var satelliteAddress = context.Settings.GetTransportAddress(satelliteLogicalAddress); context.AddSatelliteReceiver("Test satellite", satelliteAddress, PushRuntimeSettings.Default, (c, ec) => RecoverabilityAction.MoveToError(c.Failed.ErrorQueue), (builder, messageContext) => { var testContext = builder.Build <Context>(); testContext.MessageReceived = true; testContext.TransportTransactionAddedToContext = ReferenceEquals(messageContext.Extensions.Get <TransportTransaction>(), messageContext.TransportTransaction); return(Task.FromResult(true)); }); Address = satelliteAddress; }
protected override void Setup(FeatureConfigurationContext context) { var settings = context.Settings; tempQueue = "Samples.SagaMigration.Server.New"; mainQueue = settings.LocalAddress(); context.AddSatelliteReceiver( name: "DrainTempQueueSatellite", transportAddress: tempQueue, runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1), recoverabilityPolicy: (config, errorContext) => { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }, onMessage: OnMessage); }
protected override void Setup(FeatureConfigurationContext context) { var satelliteLogicalAddress = context.Settings.LogicalAddress().CreateQualifiedAddress("MySatellite"); var satelliteAddress = context.Settings.GetTransportAddress(satelliteLogicalAddress); #pragma warning disable 612, 618 context.AddSatelliteReceiver("Test satellite", satelliteAddress, TransportTransactionMode.None, PushRuntimeSettings.Default, (c, ec) => RecoverabilityAction.MoveToError(c.Failed.ErrorQueue), (builder, pushContext) => { var testContext = builder.Build <Context>(); testContext.MessageReceived = true; return(Task.FromResult(true)); }); #pragma warning restore 612, 618 Address = satelliteAddress; }
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)); }
protected override void Setup(FeatureConfigurationContext context) { var settings = context.Settings; var qualifiedAddress = settings.LogicalAddress() .CreateQualifiedAddress("New"); tempQueue = settings.GetTransportAddress(qualifiedAddress); mainQueue = settings.LocalAddress(); context.AddSatelliteReceiver( name: "DrainTempQueueSatellite", transportAddress: tempQueue, runtimeSettings: new PushRuntimeSettings(maxConcurrency: 1), recoverabilityPolicy: (config, errorContext) => { return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }, onMessage: OnMessage); }
protected override void Setup(FeatureConfigurationContext context) { var endpointQueueName = context.Settings.EndpointQueueName(); var queueAddress = new QueueAddress(endpointQueueName, null, null, "MySatellite"); var satelliteAddress = context.Settings.Get <TransportDefinition>().ToTransportAddress(queueAddress); context.AddSatelliteReceiver("Test satellite", satelliteAddress, PushRuntimeSettings.Default, (c, ec) => RecoverabilityAction.MoveToError(c.Failed.ErrorQueue), (builder, messageContext, cancellationToken) => { var testContext = builder.GetService <Context>(); testContext.MessageReceived = true; testContext.TransportTransactionAddedToContext = ReferenceEquals(messageContext.Extensions.Get <TransportTransaction>(), messageContext.TransportTransaction); return(Task.FromResult(true)); }); Address = satelliteAddress; }
RecoverabilityAction MyCustomRetryPolicy(RecoverabilityConfig config, ErrorContext context) { // early decisions and return before custom policy is invoked // i.e. MyBusinessException should always go to customized error queue if (context.Exception is MyBusinessException) { return(RecoverabilityAction.MoveToError("customErrorQueue")); } // override delayed retry decision for custom exception // i.e. MyOtherBusinessException should do fixed backoff of 5 seconds if (context.Exception is MyOtherBusinessException && context.DelayedDeliveriesPerformed <= config.Delayed.MaxNumberOfRetries) { return(RecoverabilityAction.DelayedRetry(TimeSpan.FromSeconds(5))); } // in all other cases No Immediate or Delayed Retries, go to default error queue return(RecoverabilityAction.MoveToError(config.Failed.ErrorQueue)); }
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 Endpoint() { EndpointSetup <DefaultServer>((config, context) => { var testContext = (Context)context.ScenarioContext; config.Recoverability() .CustomPolicy((cfg, errorContext) => { testContext.ErrorContexts.Add(errorContext); if (errorContext.DelayedDeliveriesPerformed >= 1) { return(RecoverabilityAction.MoveToError(cfg.Failed.ErrorQueue)); } return(RecoverabilityAction.DelayedRetry(TimeSpan.FromMilliseconds(1))); }); }); }