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 }
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); }
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)); }); }
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 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)); }
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))); }
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); }
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); }
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 void DelayedRetry(FeatureConfigurationContext context) { #region SatelliteRecoverability-DelayedRetry context.AddSatelliteReceiver( name: "CustomSatellite", transportAddress: "targetQueue", requiredTransportTransactionMode: TransportTransactionMode.TransactionScope, runtimeSettings: PushRuntimeSettings.Default, recoverabilityPolicy: (config, errorContext) => { return(RecoverabilityAction.DelayedRetry( timeSpan: TimeSpan.FromMinutes(2))); }, onMessage: OnMessage); #endregion }
public static Func<RecoverabilityConfig, ErrorContext, RecoverabilityAction> Return(RecoverabilityAction[] actions) { return new RetryPolicy(actions).Invoke; }
RetryPolicy(RecoverabilityAction[] actions) { this.actions = new Queue<RecoverabilityAction>(actions); }