public RegularModePolicy(string inputQueue, RepeatedFailuresCircuitBreaker circuitBreaker, PoisonMessageHandling poisonMessageHandling, int immediateRetries, int delayedRetries) { this.circuitBreaker = circuitBreaker; this.inputQueue = inputQueue; this.poisonMessageHandling = poisonMessageHandling; this.immediateRetries = immediateRetries; this.delayedRetries = delayedRetries; }
RawEndpointConfiguration PrepareThrottledConfig(string inputQueue, string poisonMessageQueueName, Action <TransportExtensions <T> > transportCustomization, Func <MessageContext, IDispatchMessages, Task> onMessage, PoisonMessageHandling poisonMessageHandling, int?maximumConcurrency, int immediateRetries, int delayedRetries, int circuitBreakerThreshold) { var switchedBack = false; var throttledConfig = RawEndpointConfiguration.Create(inputQueue, async(context, dispatcher) => { await onMessage(context, dispatcher); if (switchedBack) { return; } await transitionSemaphore.WaitAsync().ConfigureAwait(false); Task.Run(async() => { logger.Info("Exiting throttled mode."); try { var oldEndpoint = endpoint; var regularConfig = PrepareConfig(inputQueue, poisonMessageQueueName, transportCustomization, onMessage, poisonMessageHandling, maximumConcurrency, immediateRetries, delayedRetries, circuitBreakerThreshold, false, null); var newEndpoint = await RawEndpoint.Start(regularConfig).ConfigureAwait(false); endpoint = newEndpoint; await oldEndpoint.Stop().ConfigureAwait(false); } catch (Exception e) { logger.Error("Error when exiting throttled mode", e); } finally { transitionSemaphore.Release(); } }).Ignore(); switchedBack = true; }, poisonMessageQueueName); throttledConfig.CustomErrorHandlingPolicy(new ThrottledModePolicy(inputQueue, immediateRetries)); Task onCriticalError(ICriticalErrorContext context) { logger.Fatal($"The receiver for queue {inputQueue} has encountered a severe error that is likely related to the connectivity with the broker or the broker itself."); return(Task.CompletedTask); } throttledConfig.Settings.Set("onCriticalErrorAction", (Func <ICriticalErrorContext, Task>)onCriticalError); var transport = throttledConfig.UseTransport <T>(); transportCustomization(transport); throttledConfig.LimitMessageProcessingConcurrencyTo(1); return(throttledConfig); }
RawEndpointConfiguration PrepareConfig(string inputQueue, string poisonMessageQueueName, Action <TransportExtensions <T> > transportCustomization, Func <MessageContext, IDispatchMessages, Task> onMessage, PoisonMessageHandling poisonMessageHandling, int?maximumConcurrency, int immediateRetries, int delayedRetries, int circuitBreakerThreshold, bool autoCreateQueue, string autoCreateQueueIdentity) { var circuitBreaker = new RepeatedFailuresCircuitBreaker(inputQueue, circuitBreakerThreshold, e => { logger.Error($"Persistent error while processing messages in {inputQueue}. Entering throttled mode.", e); Task.Run(async() => { await transitionSemaphore.WaitAsync().ConfigureAwait(false); try { var oldEndpoint = endpoint; var throttledConfig = PrepareThrottledConfig(inputQueue, poisonMessageQueueName, transportCustomization, onMessage, poisonMessageHandling, maximumConcurrency, immediateRetries, circuitBreakerThreshold, delayedRetries); var newEndpoint = await RawEndpoint.Start(throttledConfig).ConfigureAwait(false); endpoint = newEndpoint; await oldEndpoint.Stop().ConfigureAwait(false); } catch (Exception ex) { logger.Error("Error when entering throttled mode", ex); } finally { transitionSemaphore.Release(); } }); }); var regularConfig = RawEndpointConfiguration.Create(inputQueue, async(context, dispatcher) => { await onMessage(context, dispatcher).ConfigureAwait(false); circuitBreaker.Success(); }, poisonMessageQueueName); regularConfig.CustomErrorHandlingPolicy(new RegularModePolicy(inputQueue, circuitBreaker, poisonMessageHandling, immediateRetries, delayedRetries)); Task onCriticalError(ICriticalErrorContext context) { logger.Fatal($"The receiver for queue {inputQueue} has encountered a severe error that is likely related to the connectivity with the broker or the broker itself."); return(Task.CompletedTask); } regularConfig.Settings.Set("onCriticalErrorAction", (Func <ICriticalErrorContext, Task>)onCriticalError); var transport = regularConfig.UseTransport <T>(); transportCustomization(transport); if (autoCreateQueue) { regularConfig.AutoCreateQueue(autoCreateQueueIdentity); } if (maximumConcurrency.HasValue) { regularConfig.LimitMessageProcessingConcurrencyTo(maximumConcurrency.Value); } return(regularConfig); }
public ThrottlingRawEndpointConfig(string queue, string poisonMessageQueueName, Action <TransportExtensions <T> > transportCustomization, Func <MessageContext, IDispatchMessages, Task> onMessage, PoisonMessageHandling poisonMessageHandling, int?maximumConcurrency, int immediateRetries, int delayedRetries, int circuitBreakerThreshold, bool autoCreateQueue, string autoCreateQueueIdentity = null) { if (immediateRetries < 0) { throw new ArgumentException("Immediate retries count must not be less than zero.", nameof(immediateRetries)); } if (delayedRetries < 0) { throw new ArgumentException("Delayed retries count must not be less than zero.", nameof(delayedRetries)); } if (circuitBreakerThreshold < 0) { throw new ArgumentException("Circuit breaker threshold must not be less than zero.", nameof(circuitBreakerThreshold)); } config = PrepareConfig(queue, poisonMessageQueueName, transportCustomization, onMessage, poisonMessageHandling, maximumConcurrency, immediateRetries, delayedRetries, circuitBreakerThreshold, autoCreateQueue, autoCreateQueueIdentity); }