Ejemplo n.º 1
0
        private EventStreamRecord ReadEventStreamRecord(byte[] recordBuffer)
        {
            var record = new EventStreamRecord();

            record.ReadFrom(recordBuffer);
            return(record);
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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));
        }
Ejemplo n.º 4
0
        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);
            }
        }