private EventStreamRecord ReadEventStreamRecord(byte[] recordBuffer) { var record = new EventStreamRecord(); record.ReadFrom(recordBuffer); return(record); }
public EventAppendResult AppendEventStreams(IEnumerable <IEventStream> eventStreams) { lock (_lockObj) { var eventStreamDict = GroupEventStreamByAggregateRoot(eventStreams); var eventAppendResult = new EventAppendResult(); foreach (var entry in eventStreamDict) { var aggregateRootId = entry.Key; var eventStreamList = entry.Value; //检查当前聚合根的事件是否合法 if (!CheckAggregateEvents(aggregateRootId, eventStreamList, eventAppendResult, out AggregateLatestVersionData aggregateLatestVersionData)) { continue; } //如果合法,则持久化事件到文件 foreach (var eventStream in eventStreamList) { var record = new EventStreamRecord { AggregateRootId = eventStream.AggregateRootId, AggregateRootType = eventStream.AggregateRootType, Version = eventStream.Version, CommandId = eventStream.CommandId, Timestamp = eventStream.Timestamp, CommandCreateTimestamp = eventStream.CommandCreateTimestamp, Events = eventStream.Events }; if (aggregateLatestVersionData != null) { record.PreviousRecordLogPosition = aggregateLatestVersionData.LogPosition; } //写入事件到文件 _eventDataChunkWriter.Write(record); //更新聚合根的内存缓存数据 RefreshMemoryCache(aggregateRootId, ref aggregateLatestVersionData, record); //添加事件到事件队列,以便进行异步持久化事件索引和命令索引 _eventStreamRecordQueue.Enqueue(record); } eventAppendResult.SuccessAggregateRootIdList.Add(aggregateRootId); } return(eventAppendResult); } }
private void RefreshMemoryCache(string aggregateRootId, ref AggregateLatestVersionData aggregateLatestVersionData, EventStreamRecord record) { if (aggregateLatestVersionData != null) { var oldLastActiveTimestamp = aggregateLatestVersionData.LastActiveTimestamp; aggregateLatestVersionData.Update(record.LogPosition, record.Version); var newLastActiveTimestamp = aggregateLatestVersionData.LastActiveTimestamp; _aggregateIndexCacheDict.UpdateTimeKeyDict(aggregateRootId, oldLastActiveTimestamp, newLastActiveTimestamp); } else { aggregateLatestVersionData = new AggregateLatestVersionData(record.LogPosition, record.Version); _aggregateIndexCacheDict.AddOrUpdate(aggregateRootId, aggregateLatestVersionData); } _commandIndexCacheDict.AddOrUpdate(record.CommandId, new CommandIndexData(record.CommandCreateTimestamp)); }
public EventAppendResult AppendEventStream(IEventStream eventStream) { lock (_lockObj) { //判断命令是否重复 var commandCacheKey = BuildCommandCacheKey(eventStream.CommandCreateTimestamp); if (_commandIndexDict.TryGetValue(commandCacheKey, out ConcurrentDictionary <string, byte> commandIndexDict)) { if (commandIndexDict.ContainsKey(eventStream.CommandId)) { return(EventAppendResult.DuplicateCommand); } } //判断版本号是否冲突,使用内存中仅保留每个聚合根最新版本的字典来实现 if (_aggregateLatestVersionDict.TryGetValue(eventStream.AggregateRootId, out AggregateLatestVersionData aggregateLatestVersionData)) { if (eventStream.Version != (aggregateLatestVersionData.Version + 1)) { return(EventAppendResult.InvalidEventVersion); } } else if (eventStream.Version != 1) { return(EventAppendResult.InvalidEventVersion); } //写入eventStream到文件 var record = new EventStreamRecord { AggregateRootId = eventStream.AggregateRootId, AggregateRootType = eventStream.AggregateRootType, Version = eventStream.Version, CommandId = eventStream.CommandId, Timestamp = eventStream.Timestamp, CommandCreateTimestamp = eventStream.CommandCreateTimestamp, Events = eventStream.Events }; if (aggregateLatestVersionData != null) { record.PreviousRecordLogPosition = aggregateLatestVersionData.LogPosition; } _eventDataChunkWriter.Write(record); //更新聚合根最新的事件版本 if (aggregateLatestVersionData != null) { aggregateLatestVersionData.Version = record.Version; aggregateLatestVersionData.LogPosition = record.LogPosition; } else { aggregateLatestVersionData = new AggregateLatestVersionData { Version = record.Version, LogPosition = record.LogPosition }; _aggregateLatestVersionDict[eventStream.AggregateRootId] = aggregateLatestVersionData; } //添加命令索引到内存字典 _commandIndexDict .GetOrAdd(commandCacheKey, k => new ConcurrentDictionary <string, byte>()) .TryAdd(eventStream.CommandId, 1); //添加事件到事件队列,以便进行异步持久化事件索引和命令索引 _eventStreamRecordQueue.Enqueue(record); return(EventAppendResult.Success); } }