Пример #1
0
        public async Task <Guid> Commit(Guid commitId, Guid startingEventId, IDictionary <string, string> commitHeaders)
        {
            Logger.Write(LogLevel.Debug, () => $"Event stream [{StreamId}] in bucket [{Bucket}] for type {typeof(T).FullName} commiting {_uncommitted.Count} events, {_pendingShots.Count} snapshots, {_outofband.Count} out of band");


            if (commitHeaders == null)
            {
                commitHeaders = new Dictionary <string, string>();
            }

            commitHeaders[CommitHeader] = commitId.ToString();

            if (_outofband.Any())
            {
                if (_oobHandler == null)
                {
                    Logger.Write(LogLevel.Warn, () => $"OOB events were used on stream [{StreamId}] but no publishers have been defined!");
                }
                else
                {
                    Logger.Write(LogLevel.Debug, () => $"Event stream [{StreamId}] in bucket [{Bucket}] publishing {_outofband.Count} out of band events to {_oobHandler.GetType().Name}");
                    await _oobHandler.Publish <T>(Bucket, StreamId, _outofband, commitHeaders).ConfigureAwait(false);
                }
                _outofband.Clear();
            }

            var wip = _uncommitted.ToList();

            if (wip.Any())
            {
                // If we increment commit id instead of depending on a commit header, ES will do the concurrency check for us
                foreach (var uncommitted in wip.Where(x => !x.EventId.HasValue))
                {
                    uncommitted.EventId = startingEventId;
                    startingEventId     = startingEventId.Increment();
                }

                Logger.Write(LogLevel.Debug, () => $"Event stream [{StreamId}] in bucket [{Bucket}] committing {wip.Count} events");
                await _store.WriteEvents <T>(Bucket, StreamId, CommitVersion, wip, commitHeaders).ConfigureAwait(false);

                _uncommitted = wip;
            }
            if (_pendingShots.Any())
            {
                Logger.Write(LogLevel.Debug, () => $"Event stream [{StreamId}] in bucket [{Bucket}] committing {_pendingShots.Count} snapshots");
                await _snapshots.WriteSnapshots <T>(Bucket, StreamId, _pendingShots, commitHeaders).ConfigureAwait(false);
            }
            Flush(true);
            return(startingEventId);
        }
Пример #2
0
        public async Task Commit(Guid commitId, IDictionary <string, string> commitHeaders)
        {
            var hasSnapshot = _pendingShot == null ? "no" : "with";

            Logger.Write(LogLevel.Info, () => $"Event stream [{StreamId}] in bucket [{Bucket}] for type {typeof(T).FullName} commiting {_uncommitted.Count} events, {_outofband.Count} out of band, {hasSnapshot} snapshot");

            // Flush events first, guarantee consistency through expected version THEN write snapshots and OOB
            if (_uncommitted.Any())
            {
                Logger.Write(LogLevel.Debug,
                             () => $"Event stream [{StreamId}] in bucket [{Bucket}] committing {Uncommitted.Count()} events");
                await _store.WriteStream <T>(this, commitHeaders).ConfigureAwait(false);
            }

            var tasks = new Task[]
            {
                Task.Run(() =>
                {
                    if (!_outofband.Any())
                    {
                        return(Task.CompletedTask);
                    }

                    if (_oobHandler == null)
                    {
                        Logger.Write(LogLevel.Warn,
                                     () => $"OOB events were used on stream [{StreamId}] but no publishers have been defined!");
                    }
                    else
                    {
                        Logger.Write(LogLevel.Debug,
                                     () => $"Event stream [{StreamId}] in bucket [{Bucket}] publishing {_outofband.Count} out of band events to {_oobHandler.GetType().Name}");
                        return(_oobHandler.Publish <T>(Bucket, StreamId, _outofband, commitHeaders));
                    }
                    return(Task.CompletedTask);
                }),
                Task.Run(() =>
                {
                    if (_pendingShot == null)
                    {
                        return(Task.CompletedTask);
                    }

                    Logger.Write(LogLevel.Debug,
                                 () => $"Event stream [{StreamId}] in bucket [{Bucket}] committing snapshot");
                    return(_snapshots.WriteSnapshots <T>(Bucket, StreamId, _pendingShot, commitHeaders));
                })
            };
            await Task.WhenAll(tasks).ConfigureAwait(false);

            Flush(true);
        }