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); }
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); }