示例#1
0
        /// <inheritdoc />
        public async Task<Dictionary<IStream, IEnumerable<IEvent>>> GetChanges(ICommand command, Time time)
        {
            var activeBranch = _manager.ActiveBranch;
            var branch = $"{command.GetType().Name}-{time.ToUnixTimeMilliseconds()}";

            await _manager.Branch(branch, time, deleteExisting: true);

            var copy = command;
            copy.Timeline = branch;
            
            var handler = _commandRegistry.GetHandler(copy);
            if (handler == null)
                throw new InvalidOperationException($"No handler found for command {command.GetType().Name}");
            await handler.Handle(copy);
            
            await _manager.Branch(activeBranch);
            
            var dict = new Dictionary<IStream, IEnumerable<IEvent>>();

            var changes = await _manager.GetChanges(branch);
            _log.StopWatch.Start("GetChanges.Read");
            foreach (var c in changes)
            {
                var stream = await _streamLocator.FindBranched(c.Key, branch);
                var e = await _eventStore.ReadStream<IEvent>(stream, stream.Version - c.Value + 1, c.Value).ToList();

                dict[c.Key] = e;
            }
            
            _log.StopWatch.Stop("GetChanges.Read");

            await _manager.DeleteBranch(branch);
            return dict;
        }
示例#2
0
        /// <inheritdoc />
        protected override BranchState[] GetStates(BranchState current)
        {
            var activeBranch = _manager.ActiveBranch;
            var commands     = GetCommands(current).ToList();
            var states       = new BranchState[commands.Count];
            var iState       = 0;

            foreach (var command in commands)
            {
                states[iState] = ApplyCommands(command, current.Timeline).Result;
                iState++;
            }

            _manager.Branch(activeBranch).Wait();

            return(states);
        }
示例#3
0
        /// <summary>
        /// Branch mutation
        /// </summary>
        /// <param name="branch">Branch id</param>
        /// <returns>Branch result</returns>
        public bool Branch(string branch)
        {
            if (branch == string.Empty)
            {
                _manager.Reset();
            }
            else
            {
                _manager.Branch(branch).Wait();
            }

            return(true);
        }
示例#4
0
        /// <inheritdoc />
        /// <summary>
        /// Wrap the handler and redirect all exception to <see cref="IErrorLog"/>
        /// </summary>
        public async Task Handle(T command)
        {
            _log.Trace($"{command.GetType().Name}", this);
            var timeline = _timeline.Id;

            if (!(command is IRetroactiveCommand) && command.Timestamp == default)
            {
                command.Timestamp = _timeline.Now;
            }
            if (command.LocalId == default)
            {
                command.LocalId = new EventId(Configuration.ReplicaName, command.Timestamp);
            }
            if (command.OriginId == default)
            {
                command.OriginId = new EventId(Configuration.ReplicaName, command.Timestamp);
            }
            command.Timeline = timeline;

            try
            {
                await _handler.Handle(command);

                if (command.StoreInLog && !command.Pure)
                {
                    await _commandLog.AppendCommand(command);
                }
            }
            catch (Exception e)
            {
                _errorLog.Add(e);

                // check that we didn't end up on wrong timeline
                if (_timeline.Id != timeline)
                {
                    var tException = new InvalidOperationException($"Execution started on {timeline} but ended on {_timeline.Id}");
                    _errorLog.Add(tException);

                    // throw tException;
                    await _branchManager.Branch(timeline);
                }

                await _commandLog.AddFailedCommand(command);
            }
        }