private void Clear(EventStreamContext context, ErrorInfo errorInfo)
 {
     if (errorInfo != null)
     {
         _commandAsyncResultManager.TryComplete(context.EventStream.CommandId, context.EventStream.AggregateRootId, errorInfo.ErrorMessage, errorInfo.Exception);
     }
     else
     {
         _commandAsyncResultManager.TryComplete(context.EventStream.CommandId, context.EventStream.AggregateRootId);
     }
     _processingCommandCache.TryRemove(context.EventStream.CommandId);
     FinishExecution(context.EventStream, context.Queue);
 }
        private void TryDispatchEventsToEventHandlers(EventStreamContext context)
        {
            Func <EventStreamContext, bool> tryDispatchEventsAction = (streamContext) => {
                if (streamContext.EventStream.Version == 1)
                {
                    return(DispatchEventsToHandlers(streamContext.EventStream));
                }
                else
                {
                    var lastPublishedVersion = _eventPublishInfoStore.GetEventPublishedVersion(streamContext.EventStream.AggregateRootId);

                    if (lastPublishedVersion + 1 == streamContext.EventStream.Version)
                    {
                        return(DispatchEventsToHandlers(streamContext.EventStream));
                    }
                    else if (lastPublishedVersion + 1 > streamContext.EventStream.Version)
                    {
                        return(true);
                    }

                    return(false);
                }
            };

            try {
                if (_retryService.TryAction("TryDispatchEvents", () => tryDispatchEventsAction(context), 3))
                {
                    Clear(context);
                }
                else
                {
                    _retryService.RetryInQueue(
                        new ActionInfo(
                            "TryDispatchEvents",
                            (obj) => tryDispatchEventsAction(obj as EventStreamContext),
                            context,
                            new ActionInfo(
                                "DispatchEventsSuccessAction",
                                (data) => { Clear(data as EventStreamContext); return(true); },
                                context, null)
                            )
                        );
                }
            }
            catch (Exception ex) {
                _logger.Error(string.Format("Exception raised when dispatching events:{0}", context.EventStream.GetStreamInformation()), ex);
            }
        }
        private bool CommitEvents(EventStreamContext eventStreamContext)
        {
            var errorInfo         = new ErrorInfo();
            var synchronizeResult = TryCallSynchronizersBeforeEventPersisting(eventStreamContext.EventStream, errorInfo);

            if (synchronizeResult == SynchronizeResult.SynchronizerConcurrentException)
            {
                return(false);
            }
            else if (synchronizeResult == SynchronizeResult.Failed)
            {
                Clear(eventStreamContext, errorInfo);
                return(true);
            }
            else
            {
                var persistSuccessActionInfo = new ActionInfo(
                    "PersistSuccessAction",
                    (obj) => {
                    var context = obj as EventStreamContext;
                    if (context.HasConcurrentException)
                    {
                        var retryCommandSuccessAction = new ActionInfo(
                            "RetryCommandSuccessAction",
                            (data) => {
                            var streamContext = data as EventStreamContext;
                            FinishExecution(streamContext.EventStream, streamContext.Queue);
                            return(true);
                        },
                            context, null);
                        RetryCommand(context, context.ErrorInfo, retryCommandSuccessAction);
                    }
                    else
                    {
                        TryRefreshMemoryCache(context.EventStream);
                        TryCallSynchronizersAfterEventPersisted(context.EventStream);
                        TryPublishEvents(context.EventStream, new ActionInfo("PublishSuccessAction", (data) => { Clear(data as EventStreamContext); return(true); }, context, null));
                    }
                    return(true);
                },
                    eventStreamContext,
                    null);

                TryPersistEvents(eventStreamContext, persistSuccessActionInfo);

                return(true);
            }
        }
 private void RetryCommand(EventStreamContext eventStreamContext, ErrorInfo errorInfo, ActionInfo successActionInfo)
 {
     if (!eventStreamContext.EventStream.IsRestoreFromStorage())
     {
         var command = _processingCommandCache.Get(eventStreamContext.EventStream.CommandId);
         if (command != null)
         {
             _retryCommandService.RetryCommand(command, eventStreamContext.EventStream, errorInfo, successActionInfo);
         }
         else
         {
             _logger.ErrorFormat("The command need to retry cannot be found from command processing cache, commandId:{0}", eventStreamContext.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.", eventStreamContext.EventStream.CommandId);
     }
 }
        public override void Execute(EventStream message, IMessageQueue <EventStream> queue)
        {
            var eventStreamContext = new EventStreamContext {
                EventStream = message, Queue = queue
            };

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

            if (!_retryService.TryAction("TryCommitEvents", () => tryCommitEventsAction(eventStreamContext), 3))
            {
                _retryService.RetryInQueue(new ActionInfo("TryCommitEvents", (obj) => tryCommitEventsAction(obj as EventStreamContext), eventStreamContext, null));
            }
        }
        private void TryPersistEvents(EventStreamContext eventStreamContext, ActionInfo successActionInfo)
        {
            Func <EventStreamContext, bool> tryPersistEventsAction = (context) => {
                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 = errorMessage, Exception = ex
                        });
                        return(true);
                    }

                    return(false);
                }
            };

            if (_retryService.TryAction("TryPersistEvents", () => tryPersistEventsAction(eventStreamContext), 3))
            {
                successActionInfo.Action(successActionInfo.Data);
            }
            else
            {
                _retryService.RetryInQueue(new ActionInfo("TryPersistEvents", (obj) => tryPersistEventsAction(obj as EventStreamContext), eventStreamContext, successActionInfo));
            }
        }
 private void Clear(EventStreamContext context)
 {
     UpdatePublishedEventStreamVersion(context.EventStream);
     FinishExecution(context.EventStream, context.Queue);
 }
 private void Clear(EventStreamContext context)
 {
     Clear(context, null);
 }