/// <summary> /// Includes an outbox in the consume filter path, which delays outgoing messages until the return path /// of the pipeline returns to the outbox filter. At this point, the message execution pipeline should be /// nearly complete with only the ack remaining. If an exception is thrown, the messages are not sent/published. /// </summary> /// <param name="configurator"></param> /// <param name="configure">Configure the outbox</param> public static void UseInMemoryOutbox <TSaga>(this ISagaConfigurator <TSaga> configurator, Action <IOutboxConfigurator> configure = default) where TSaga : class, ISaga { if (configurator == null) { throw new ArgumentNullException(nameof(configurator)); } var observer = new InMemoryOutboxSagaConfigurationObserver <TSaga>(configurator, configure); configurator.ConnectSagaConfigurationObserver(observer); }
/// <summary> /// Configure scheduled redelivery for the saga, regardless of message type. /// </summary> /// <param name="configurator"></param> /// <param name="configure"></param> public static void UseScheduledRedelivery <TSaga>(this ISagaConfigurator <TSaga> configurator, Action <IRetryConfigurator> configure) where TSaga : class, ISaga { if (configurator == null) { throw new ArgumentNullException(nameof(configurator)); } var observer = new MessageRedeliverySagaConfigurationObserver <TSaga>(configurator, configure); configurator.ConnectSagaConfigurationObserver(observer); }
/// <summary> /// Limits the number of concurrent messages consumed by the saga, regardless of message type. /// </summary> /// <param name="configurator"></param> /// <param name="concurrentMessageLimit">The concurrent message limit for all message types for the saga</param> public static void UseConcurrentMessageLimit <TSaga>(this ISagaConfigurator <TSaga> configurator, int concurrentMessageLimit) where TSaga : class, ISaga { if (configurator == null) { throw new ArgumentNullException(nameof(configurator)); } var observer = new ConcurrencyLimitSagaConfigurationObserver <TSaga>(configurator, concurrentMessageLimit); configurator.ConnectSagaConfigurationObserver(observer); }
/// <summary> /// Configures the message retry for the consumer consumer, regardless of message type. /// </summary> /// <param name="configurator"></param> /// <param name="busFactoryConfigurator"> /// The bus factory configurator, to connect the observer, to cancel retries if the bus is stopped /// </param> /// <param name="configure"></param> public static void UseMessageRetry <TSaga>(this ISagaConfigurator <TSaga> configurator, IBusFactoryConfigurator busFactoryConfigurator, Action <IRetryConfigurator> configure) where TSaga : class, ISaga { if (configurator == null) { throw new ArgumentNullException(nameof(configurator)); } var retryObserver = new RetryBusObserver(); busFactoryConfigurator.ConnectBusObserver(retryObserver); var observer = new MessageRetrySagaConfigurationObserver <TSaga>(configurator, retryObserver.Stopping, configure); configurator.ConnectSagaConfigurationObserver(observer); }
/// <summary> /// Limits the number of concurrent messages consumed by the saga, regardless of message type. /// </summary> /// <param name="configurator"></param> /// <param name="concurrentMessageLimit">The concurrent message limit for all message types for the saga</param> /// <param name="managementEndpointConfigurator">A management endpoint configurator to support runtime adjustment</param> /// <param name="id">An identifier for the concurrency limit to allow selective adjustment</param> public static void UseConcurrentMessageLimit <TSaga>(this ISagaConfigurator <TSaga> configurator, int concurrentMessageLimit, IManagementEndpointConfigurator managementEndpointConfigurator, string id = null) where TSaga : class, ISaga { if (configurator == null) { throw new ArgumentNullException(nameof(configurator)); } var observer = new ConcurrencyLimitSagaConfigurationObserver <TSaga>(configurator, concurrentMessageLimit, id); configurator.ConnectSagaConfigurationObserver(observer); managementEndpointConfigurator.Instance(observer.Limiter, x => { x.UseConcurrentMessageLimit(1); x.Message <SetConcurrencyLimit>(m => m.UseRetry(r => r.None())); }); }