/// <summary>
        /// Enabling fluent configuration of circuit breakers
        /// </summary>
        /// <param name="configurer"></param>
        /// <param name="circuitBreakerBuilder"></param>
        public static void EnableCircuitBreaker(this OptionsConfigurer configurer, Action <CircuitBreakerConfigurationBuilder> circuitBreakerBuilder)
        {
            var builder = new CircuitBreakerConfigurationBuilder();

            circuitBreakerBuilder?.Invoke(builder);

            configurer.Register(context => new CircuitBreakerEvents());

            configurer.Register(context =>
            {
                var loggerFactory        = context.Get <IRebusLoggerFactory>();
                var asyncTaskFactory     = context.Get <IAsyncTaskFactory>();
                var circuitBreakerEvents = context.Get <CircuitBreakerEvents>();
                var options         = context.Get <Options>();
                var circuitBreakers = builder.Build(context);

                return(new MainCircuitBreaker(circuitBreakers, loggerFactory, asyncTaskFactory, new Lazy <IBus>(context.Get <IBus>), circuitBreakerEvents, options));
            });

            configurer.Decorate <IErrorTracker>(context =>
            {
                var innerErrorTracker = context.Get <IErrorTracker>();
                var circuitBreaker    = context.Get <MainCircuitBreaker>();

                return(new CircuitBreakerErrorTracker(innerErrorTracker, circuitBreaker));
            });
        }
        /// <summary>
        /// Makes Rebus "legacy compatible", i.e. enables wire-level compatibility with older Rebus versions. WHen this is enabled,
        /// all endpoints need to be old Rebus endpoints or new Rebus endpoints with this feature enabled
        /// </summary>
        public static void EnableLegacyCompatibility(this OptionsConfigurer configurer, Encoding encoding, bool propagateAutoCorrelationSagaId = true)
        {
            configurer.Register <ISerializer>(c =>
            {
                return(new LegacyCompatibilitySerializer(encoding ?? LegacyCompatibilitySerializer.DefaultEncoding));
            });

            configurer.Decorate(c =>
            {
                var pipeline = c.Get <IPipeline>();

                pipeline = new PipelineStepConcatenator(pipeline)
                           .OnReceive(new MapLegacyHeadersIncomingStep(propagateAutoCorrelationSagaId), PipelineAbsolutePosition.Front);

                // unpack object[] of transport message
                pipeline = new PipelineStepInjector(pipeline)
                           .OnReceive(new UnpackLegacyMessageIncomingStep(), PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep));

                // pack into object[]
                pipeline = new PipelineStepInjector(pipeline)
                           .OnSend(new PackLegacyMessageOutgoingStep(), PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep));

                pipeline = new PipelineStepInjector(pipeline)
                           .OnSend(new MapLegacyHeadersOutgoingStep(propagateAutoCorrelationSagaId), PipelineRelativePosition.Before, typeof(SendOutgoingMessageStep));

                return(pipeline);
            });
        }
Пример #3
0
        /// <summary>
        /// Enables async/await-based request/reply whereby a request can be sent using the <see cref="AsyncBusExtensions.SendRequest{TReply}"/> method
        /// which can be awaited for a corresponding reply.
        /// </summary>
        public static void EnableSynchronousRequestReply(this OptionsConfigurer configurer, int replyMaxAgeSeconds = 10)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }

            if (replyMaxAgeSeconds <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(replyMaxAgeSeconds), replyMaxAgeSeconds,
                                                      "Please supply a positive value for the max age of a reply (i.e. how long to keep a reply until we give up on returning it)");
            }

            configurer.Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var asyncTaskFactory   = c.Get <IAsyncTaskFactory>();
                var replyMaxAge        = TimeSpan.FromSeconds(replyMaxAgeSeconds);
                var step = new ReplyHandlerStep(AsyncBusExtensions.Messages, rebusLoggerFactory, asyncTaskFactory, replyMaxAge);
                return(step);
            });

            configurer.Decorate <IPipeline>(c =>
            {
                var pipeline = c.Get <IPipeline>();
                var step     = c.Get <ReplyHandlerStep>();
                return(new PipelineStepInjector(pipeline)
                       .OnReceive(step, PipelineRelativePosition.Before, typeof(ActivateHandlersStep)));
            });
        }
Пример #4
0
        /// <summary>
        /// Enables auto-scaling. When enabled, the bus will always start out with one single worker, possibly adding workers
        /// up until <paramref name="maxNumberOfWorkers"/>.
        /// Max parallelism can be set with <paramref name="maxParallelism"/>, which would otherwise default to the same as the
        /// number of workers.
        /// At most one worker will be added/removed, and the interval with which this happens is configured by setting
        /// <paramref name="adjustmentIntervalSeconds"/> (default: 10 s)
        /// </summary>
        public static void EnableAutoScaling(this OptionsConfigurer configurer, int maxNumberOfWorkers, int?maxParallelism = null, int adjustmentIntervalSeconds = 10)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }
            if (adjustmentIntervalSeconds < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(adjustmentIntervalSeconds), adjustmentIntervalSeconds,
                                                      "Please provide a value of at least 1 for the adjustment interval");
            }

            // decorate the transport so the auto-scaler gets to see how many messages are received
            configurer.Decorate <ITransport>(c => c.Get <AutoScaler>());

            // register auto-scaler
            configurer.Register(c =>
            {
                var options = c.Get <Options>();

                options.MaxParallelism  = maxParallelism ?? maxNumberOfWorkers;
                options.NumberOfWorkers = 1;

                var transport          = c.Get <ITransport>();
                var asyncTaskFactory   = c.Get <IAsyncTaskFactory>();
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();

                return(new AutoScaler(transport, rebusLoggerFactory, maxNumberOfWorkers, asyncTaskFactory, c.Get <IBus>, adjustmentIntervalSeconds));
            });
        }
Пример #5
0
 public static OptionsConfigurer UseOracleAQRetryStrategy(this OptionsConfigurer optionsConfigurer)
 {
     optionsConfigurer.Register <IRetryStrategy>(c =>
     {
         return(new OracleAQRetryStrategy());
     });
     return(optionsConfigurer);
 }
        /// <summary>
        /// Makes Rebus "legacy compatible", i.e. enables wire-level compatibility with older Rebus versions. WHen this is enabled,
        /// all endpoints need to be old Rebus endpoints or new Rebus endpoints with this feature enabled
        /// </summary>
        public static void EnableLegacyCompatibility(this OptionsConfigurer configurer)
        {
            configurer.Register(c => new LegacyFlag());

            configurer.Register <ISerializer>(c =>
            {
                var specialSettings = LegacySubscriptionMessagesBinder.JsonSerializerSettings;
                var legacyEncoding  = Encoding.UTF7;
                var jsonSerializer  = new CustomJsonSerializer(specialSettings, legacyEncoding);
                return(jsonSerializer);
            });

            configurer.Decorate(c =>
            {
                var pipeline = c.Get <IPipeline>();

                // map headers of incoming message from v1 to v2
                pipeline = new PipelineStepConcatenator(pipeline)
                           .OnReceive(new MapLegacyHeadersIncomingStep(), PipelineAbsolutePosition.Front);

                // unpack object[] of transport message
                pipeline = new PipelineStepInjector(pipeline)
                           .OnReceive(new UnpackLegacyMessageIncomingStep(), PipelineRelativePosition.After, typeof(DeserializeIncomingMessageStep));

                // pack into object[]
                pipeline = new PipelineStepInjector(pipeline)
                           .OnSend(new PackLegacyMessageOutgoingStep(), PipelineRelativePosition.Before, typeof(SerializeOutgoingMessageStep));

                pipeline = new PipelineStepInjector(pipeline)
                           .OnSend(new MapLegacyHeadersOutgoingStep(), PipelineRelativePosition.Before, typeof(SendOutgoingMessageStep));

                //pipeline = new PipelineStepInjector(pipeline)
                //    .OnReceive(new HandleLegacySubscriptionRequestIncomingStep(c.Get<ISubscriptionStorage>(), c.Get<LegacySubscriptionMessageSerializer>()), PipelineRelativePosition.Before, typeof(MapLegacyHeadersIncomingStep));

                return(pipeline);
            });
        }
Пример #7
0
        /// <summary>
        ///     Registers a custom IErrorHandler which emits events for any exceptions raised by a command
        /// </summary>
        /// <param name="configurer"></param>
        /// <param name="provider"></param>
        public static void HandleCommandsEvents(this OptionsConfigurer configurer, IServiceProvider provider)
        {
            configurer.Register <IErrorHandler>(c =>
            {
                var simpleRetryStrategySettings = c.Get <SimpleRetryStrategySettings>();
                var transport          = c.Get <ITransport>();
                var serializer         = c.Get <ISerializer>();
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                return(new CommandsErrorHandler(provider, serializer, simpleRetryStrategySettings, transport, rebusLoggerFactory));
            });

            configurer.Decorate <IPipeline>(c =>
            {
                var pipeline = c.Get <IPipeline>();
                var step     = new CompleteCommandEventStep(c.Get <IErrorTracker>(), provider);

                return(new PipelineStepInjector(pipeline)
                       .OnReceive(step, PipelineRelativePosition.After, typeof(DispatchIncomingMessageStep)));
            });
        }
        /// <summary>
        /// Enables async/await-based request/reply whereby a request can be sent using the <see cref="AsyncBusExtensions.SendRequest{TReply}"/> method
        /// which can be awaited for a corresponding reply.
        /// </summary>
        public static void EnableSynchronousRequestReply(this OptionsConfigurer configurer)
        {
            if (configurer == null)
            {
                throw new ArgumentNullException(nameof(configurer));
            }

            configurer.Register(c =>
            {
                var rebusLoggerFactory = c.Get <IRebusLoggerFactory>();
                var step = new ReplyHandlerStep(AsyncBusExtensions.Messages, rebusLoggerFactory);
                return(step);
            });

            configurer.Decorate <IPipeline>(c =>
            {
                var pipeline = c.Get <IPipeline>();
                var step     = c.Get <ReplyHandlerStep>();
                return(new PipelineStepInjector(pipeline)
                       .OnReceive(step, PipelineRelativePosition.Before, typeof(ActivateHandlersStep)));
            });
        }