Exemple #1
0
        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));
        }
Exemple #2
0
        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);
        }
Exemple #9
0
 internal override IConnectedProjectionMessageHandler ApplyOn(IConnectedProjectionMessageHandler messageHandler)
 => messageHandler;
Exemple #10
0
 internal abstract IConnectedProjectionMessageHandler ApplyOn(IConnectedProjectionMessageHandler messageHandler);