void AppendToStream(IIdentity id, string envelopeId, Applied then, string explanation) { var stream = _factory.GetOrCreateStream(IdentityConvert.ToStream(id)); var b = new EnvelopeBuilder("unknown"); b.AddString("caused-by", envelopeId); if (!String.IsNullOrEmpty(explanation)) { b.AddString("explain", explanation); } foreach (var e in then.Events) { b.AddItem((object)e); } var data = _streamer.SaveEnvelopeData(b.Build()); Context.Debug("?? Append {0} at v{3} to '{1}' in thread {2}", then.Events.Count, IdentityConvert.ToStream(id), Thread.CurrentThread.ManagedThreadId, then.Version); if (!stream.TryAppend(data, TapeAppendCondition.VersionIs(then.Version))) { throw new InvalidOperationException("Failed to update the stream - it has been changed concurrently"); } }
void Dispatch(string id, IEnumerable <ICommand> commands) { var stream = _factory.GetOrCreateStream(id); var records = stream.ReadRecords(0, int.MaxValue).ToList(); var events = records .Select(tr => _streamer.ReadAsEnvelopeData(tr.Data)) .SelectMany(i => i.Items) .Select(i => (IEvent)i.Content) .ToList(); var then = AggregateFactory .LoadProject(events, commands) .Select(e => new MessageBuilder(e.GetType(), e)).ToList(); if (then.Count == 0) { return; } // events are stored here as envelopes ) var b = new EnvelopeBuilder("unknown"); foreach (var e in then) { b.Items.Add(e); } var version = records.Count == 0 ? 0 : records.Last().Version; var data = _streamer.SaveEnvelopeData(b.Build()); var result = stream.TryAppend(data, TapeAppendCondition.VersionIs(version)); if (!result) { throw new InvalidOperationException( "Data was modified concurrently, and we don't have merging implemented, yet"); } var args = _path.Split(':'); IQueueWriterFactory factory; if (!_queue.TryGet(args[0], out factory)) { throw new InvalidOperationException("Not found " + _path); } var arVersion = events.Count + 1; var arName = id; for (int i = 0; i < then.Count; i++) { var name = string.Format("{0}/{1}/{2}", arName, arVersion, i); var builder = new EnvelopeBuilder(name); builder.Items.Add(then[i]); builder.AddString("from-entity", arName); factory.GetWriteQueue(args[1]).PutMessage(builder.Build()); } }