示例#1
0
        private void TryPersistEvents(EventStreamContext context, Action successAction)
        {
            Func <bool> tryPersistEvents = () =>
            {
                try
                {
                    _eventStore.Append(context.EventStream);
                    return(true);
                }
                catch (Exception ex)
                {
                    if (ex is ConcurrentException && IsEventStreamCommitted(context.EventStream))
                    {
                        return(true);
                    }

                    var errorMessage = string.Format("{0} raised when persisting events:{1}", ex.GetType().Name, context.EventStream.GetStreamInformation());
                    _logger.Error(errorMessage, ex);

                    if (ex is ConcurrentException)
                    {
                        context.SetConcurrentException(new ErrorInfo(errorMessage, ex));
                        return(true);
                    }

                    return(false);
                }
            };

            _retryService.TryAction("TryPersistEvents", tryPersistEvents, 3, successAction);
        }
        private void TryDispatchEventsToEventHandlers(EventStreamContext context)
        {
            Func <bool> tryDispatchEvents = () =>
            {
                var eventStream = context.EventStream;
                switch (eventStream.Version)
                {
                case 1:
                    return(DispatchEventsToHandlers(eventStream));

                default:
                    var lastPublishedVersion = _eventPublishInfoStore.GetEventPublishedVersion(eventStream.AggregateRootId);
                    if (lastPublishedVersion + 1 == eventStream.Version)
                    {
                        return(DispatchEventsToHandlers(eventStream));
                    }
                    return(lastPublishedVersion + 1 > eventStream.Version);
                }
            };

            try
            {
                _retryService.TryAction("TryDispatchEvents", tryDispatchEvents, 3, () => Clear(context));
            }
            catch (Exception ex)
            {
                _logger.Error(string.Format("Exception raised when dispatching events:{0}", context.EventStream.GetStreamInformation()), ex);
            }
        }
        public void SetUp()
        {
            _aggregateId       = _fixture.Create <string>();
            _cancellationToken = new CancellationToken();
            _eventStreamMock   = new Mock <IEventStream>();

            var creditAmount1 = _fixture.Create <decimal>();
            var creditAmount2 = _fixture.Create <decimal>();
            var debitAmount   = _fixture.Create <decimal>();

            _expectedAccountBalance = creditAmount1 + creditAmount2 - debitAmount;

            _committedEvents = new List <object> {
                new AccountCreated {
                    AccountId = _aggregateId
                },
                new AccountCredited {
                    Amount = creditAmount1
                },
                new AccountDebited {
                    Amount = debitAmount
                },
                new AccountCredited {
                    Amount = creditAmount2
                }
            };

            _eventStreamContext = new EventStreamContext(_committedEvents, _fixture.Create <string>());
            _eventStreamMock.Setup(x => x.ReadAsync(_aggregateId, _cancellationToken)).ReturnsAsync(_eventStreamContext);

            _sut = new AggregateRepository <BankAccount>(_eventStreamMock.Object);
        }
        public async Task NotThrowException_WhenGettingAggregate_GivenEventStreamIsEmpty()
        {
            var eventStreamContext = new EventStreamContext(new List <object>(), _fixture.Create <string>());

            _eventStreamMock.Setup(x => x.ReadAsync(_aggregateId, _cancellationToken)).ReturnsAsync(eventStreamContext);

            Func <Task> act = async() => await _sut.GetAsync(_aggregateId, CancellationToken.None);

            await act.Should().NotThrowAsync <Exception>();
        }
示例#5
0
        /// <summary>Execute the given event stream.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="queue"></param>
        public override void Execute(EventStream message, IMessageQueue <EventStream> queue)
        {
            var context = new EventStreamContext {
                EventStream = message, Queue = queue
            };

            Func <bool> tryCommitEvents = () =>
            {
                try
                {
                    return(CommitEvents(context));
                }
                catch (Exception ex)
                {
                    _logger.Error(string.Format("Exception raised when committing events:{0}.", context.EventStream.GetStreamInformation()), ex);
                    return(false);
                }
            };

            _retryService.TryAction("TryCommitEvents", tryCommitEvents, 3, () => { });
        }
示例#6
0
        private void RetryCommand(EventStreamContext context, ErrorInfo errorInfo, Action successAction)
        {
            var eventStream = context.EventStream;

            if (!eventStream.IsRestoreFromStorage())
            {
                var commandInfo = _processingCommandCache.Get(eventStream.CommandId);
                if (commandInfo != null)
                {
                    _retryCommandService.RetryCommand(commandInfo, eventStream, errorInfo, successAction);
                }
                else
                {
                    _logger.ErrorFormat("The command need to retry cannot be found from command processing cache, commandId:{0}", eventStream.CommandId);
                }
            }
            else
            {
                _logger.InfoFormat("The command with id {0} will not be retry as the current event stream is restored from the message store.", eventStream.CommandId);
            }
        }
示例#7
0
        private bool CommitEvents(EventStreamContext context)
        {
            var synchronizeResult = TryCallSynchronizersBeforeEventPersisting(context.EventStream);

            switch (synchronizeResult.Status)
            {
            case SynchronizeStatus.SynchronizerConcurrentException:
                return(false);

            case SynchronizeStatus.Failed:
                Clear(context, synchronizeResult.ErrorInfo);
                return(true);

            default:
            {
                Action persistSuccessAction = () =>
                {
                    if (context.HasConcurrentException)
                    {
                        TryRefreshMemoryCache(context.EventStream);
                        RetryCommand(context, context.ErrorInfo, () => FinishExecution(context.EventStream, context.Queue));
                    }
                    else
                    {
                        TryRefreshMemoryCache(context.EventStream);
                        TryCallSynchronizersAfterEventPersisted(context.EventStream);
                        TryPublishEvents(context.EventStream, () => Clear(context));
                    }
                };

                TryPersistEvents(context, persistSuccessAction);

                return(true);
            }
            }
        }
示例#8
0
 private void Clear(EventStreamContext context, ErrorInfo errorInfo = null)
 {
     _commandAsyncResultManager.TryComplete(context.EventStream.CommandId, context.EventStream.AggregateRootId, errorInfo);
     _processingCommandCache.TryRemove(context.EventStream.CommandId);
     FinishExecution(context.EventStream, context.Queue);
 }
 private void Clear(EventStreamContext context)
 {
     UpdatePublishedEventStreamVersion(context.EventStream);
     FinishExecution(context.EventStream, context.Queue);
 }