예제 #1
0
    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
    }
예제 #2
0
    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);
    }
예제 #3
0
        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));
        }
예제 #4
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));
        }
 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));
        }
예제 #9
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)));
        }
예제 #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);
        }
    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);
    }
예제 #13
0
        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
        }
예제 #14
0
        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);
 }