internal override IConnectedProjectionMessageHandler ApplyOn(IConnectedProjectionMessageHandler messageHandler) { var projection = messageHandler.Projection; var messageHandlerLogger = messageHandler.Logger; void LogRetryAttempt(Exception exception, TimeSpan waitTime, int attempt, Context context) => messageHandlerLogger .LogWarning( exception, "Projection '{Projection}' failed. Retry attempt #{RetryAttempt} in {RetryTime} seconds.", projection, attempt, waitTime.TotalSeconds); async Task ExecuteWithRetryPolicy(IEnumerable <StreamMessage> messages, IStreamGapStrategy streamGapStrategy, CancellationToken token) { await Policy .Handle <TException>() .WaitAndRetryAsync( _numberOfRetries, attempt => _delay.Multiply(attempt), LogRetryAttempt) .ExecuteAsync(async ct => await messageHandler.HandleAsync(messages, streamGapStrategy, ct), token); } return(new RetryMessageHandler(ExecuteWithRetryPolicy, projection, messageHandlerLogger)); }
public static IConnectedProjectionMessageHandler WithPolicy( this IConnectedProjectionMessageHandler connectedProjectionMessageHandler, MessageHandlingRetryPolicy retryPolicy) { if (connectedProjectionMessageHandler == null) { throw new ArgumentNullException(nameof(connectedProjectionMessageHandler)); } if (retryPolicy == null) { throw new ArgumentNullException(nameof(retryPolicy)); } return(retryPolicy.ApplyOn(connectedProjectionMessageHandler)); }
public WhenApplyingALinearBackoffPolicyOnAHandler() { _fixture = new Fixture() .CustomizeConnectedProjectionIdentifiers(); _handlerWithoutPolicy = new MessageHandlerWithExecutionTracking( _fixture.Create <ConnectedProjectionIdentifier>(), new Mock <ILogger>().Object); var numberOfRetries = _fixture.CreatePositive <int>() + 1; _numberOfExpectedAttempts = Times.Once(); var initialWait = TimeSpan.FromMilliseconds(_fixture.CreatePositive <int>()); var linearBackoffPolicy = new LinearBackOff <RetryException>(numberOfRetries, initialWait); _sut = linearBackoffPolicy.ApplyOn(_handlerWithoutPolicy); }
public WhenMessageHandlerThrowsAnExceptionThatWasNotDefinedToRetry() { var fixture = new Fixture() .CustomizeConnectedProjectionIdentifiers(); _handlerWithoutPolicy = new MessageHandlerWithExecutionTracking( fixture.Create <ConnectedProjectionIdentifier>(), new FakeLoggerFactory().ResolveLoggerMock <MessageHandlerWithExecutionTracking>().AsLogger(), new DoNotRetryException()); var numberOfRetries = fixture.CreatePositive <int>() + 1; var initialWait = TimeSpan.FromMilliseconds(fixture.CreatePositive <int>()); _messages = fixture.CreateMany <StreamMessage>().ToList(); _sut = new LinearBackOff <RetryException>(numberOfRetries, initialWait) .ApplyOn(_handlerWithoutPolicy); }
public ConnectedProjection( Func <Owned <IConnectedProjectionContext <TContext> > > contextFactory, TConnectedProjection connectedProjection, IConnectedProjectionSettings settings, ILoggerFactory loggerFactory) { Info = new ConnectedProjectionInfo( typeof(TConnectedProjection).GetProjectionName(), typeof(TConnectedProjection).GetProjectionDescription()); _settings = settings ?? throw new ArgumentNullException(nameof(settings)); ContextFactory = contextFactory ?? throw new ArgumentNullException(nameof(contextFactory)); ConnectedProjectionMessageHandler = new ConnectedProjectionMessageHandler <TContext>( Id, connectedProjection?.Handlers ?? throw new ArgumentNullException(nameof(connectedProjection)), ContextFactory, loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory)) ).WithPolicy(_settings.RetryPolicy); }
public WhenMessageHandlerThrowsAnExceptionThatWasNotDefinedToRetryAfterRetrying() { var fixture = new Fixture() .CustomizeConnectedProjectionIdentifiers(); _exceptionSequence = new Exception[] { new RetryException(), new DoNotRetryException() }; _loggerMock = new FakeLoggerFactory().ResolveLoggerMock <MessageHandlerWithExecutionTracking>(); _projection = fixture.Create <ConnectedProjectionIdentifier>(); _handlerWithoutPolicy = new MessageHandlerWithExecutionTracking( _projection, _loggerMock.AsLogger(), _exceptionSequence); var numberOfRetries = _exceptionSequence.Count(exception => exception is RetryException); _numberOfExpectedAttempts = Times.Exactly(1 + numberOfRetries); _initialWait = TimeSpan.FromMilliseconds(fixture.CreatePositive <int>()); _messages = fixture.CreateMany <StreamMessage>().ToList(); _sut = new LinearBackOff <RetryException>(numberOfRetries, _initialWait) .ApplyOn(_handlerWithoutPolicy); }
public WhenMessageHandlerThrowsTheExceptionDefinedInThePolicyMoreThanTheNumberOfRetries() { var fixture = new Fixture() .CustomizeConnectedProjectionIdentifiers(); var exceptionSequence = fixture .CreateMany <RetryException>(2, 10) .ToArray <Exception>(); _loggerMock = new FakeLoggerFactory().ResolveLoggerMock <MessageHandlerWithExecutionTracking>(); _projection = fixture.Create <ConnectedProjectionIdentifier>(); _handlerWithoutPolicy = new MessageHandlerWithExecutionTracking( _projection, _loggerMock.AsLogger(), exceptionSequence); _numberOfRetries = exceptionSequence.Length - 1; _numberOfExpectedAttempts = Times.Exactly(1 + _numberOfRetries); _initialWait = TimeSpan.FromMilliseconds(fixture.CreatePositive <int>()); _messages = fixture.CreateMany <StreamMessage>().ToList(); _sut = new LinearBackOff <RetryException>(_numberOfRetries, _initialWait) .ApplyOn(_handlerWithoutPolicy); }
public WhenApplyingNoRetriesPolicyOnAHandler() { _handlerWithoutPolicy = new Mock <IConnectedProjectionMessageHandler>().Object; _sut = new NoRetries().ApplyOn(_handlerWithoutPolicy); }
internal override IConnectedProjectionMessageHandler ApplyOn(IConnectedProjectionMessageHandler messageHandler) => messageHandler;
internal abstract IConnectedProjectionMessageHandler ApplyOn(IConnectedProjectionMessageHandler messageHandler);