Beispiel #1
0
        /// <summary>
        /// Save
        /// </summary>
        /// <param name="snapshotHeaders"></param>
        /// <returns></returns>
        public async Task SaveAsync(IEnumerable <AggregateSnapshotHeader> snapshotHeaders)
        {
            var queue = new ConcurrentQueue <AggregateSnapshotData>();

            foreach (var snapshotHeader in snapshotHeaders)
            {
                try
                {
                    var            aggregateRootType             = _typeNameProvider.GetType(snapshotHeader.AggregateRootTypeName);
                    IAggregateRoot aggregateRoot                 = null;
                    IEnumerable <DomainEventStream> eventStreams = null;
                    var lastSnapshotData = await _snapshotStore.FindLatestAsync(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName);

                    if (lastSnapshotData != null)
                    {
                        try
                        {
                            using (var ms = new MemoryStream())
                            {
                                await ms.WriteAsync(lastSnapshotData.Data, 0, lastSnapshotData.Data.Length);

                                await ms.FlushAsync();

                                ms.Position   = 0;
                                aggregateRoot = _binaryFormatter.Deserialize(ms) as IAggregateRoot;
                            }
                        }
                        catch
                        {
                            aggregateRoot = null;
                        }
                    }
                    if (aggregateRoot == null)
                    {
                        // 无快照
                        aggregateRoot = _aggregateRootFactory.CreateAggregateRoot(aggregateRootType);
                        eventStreams  = await _eventStore.QueryAggregateEventsAsync(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName, 1, snapshotHeader.Version);
                    }
                    else
                    {
                        eventStreams = await _eventStore.QueryAggregateEventsAsync(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName, lastSnapshotData.Version + 1, snapshotHeader.Version);
                    }
                    if (eventStreams != null && eventStreams.Any())
                    {
                        aggregateRoot.ReplayEvents(eventStreams);
                        using (var ms = new MemoryStream())
                        {
                            _binaryFormatter.Serialize(ms, aggregateRoot);
                            await ms.FlushAsync();

                            ms.Position = 0;
                            byte[] buffer = new byte[ms.Length];
                            await ms.ReadAsync(buffer, 0, buffer.Length);

                            queue.Enqueue(new AggregateSnapshotData(snapshotHeader.AggregateRootId, snapshotHeader.AggregateRootTypeName, aggregateRoot.Version, buffer));
                        }
                    }
                }
                catch (Exception ex)
                {
                    _logger.Error($"Save snapshot fail:{ex.Message}. AggregateRootId={snapshotHeader.AggregateRootId},AggregateRootTypeName={snapshotHeader.AggregateRootTypeName}", ex);
                }
            }

            var snapshotDataList = new List <AggregateSnapshotData>();

            while (queue.TryDequeue(out AggregateSnapshotData snapshotData))
            {
                snapshotDataList.Add(snapshotData);
                if (snapshotDataList.Count == _batchSaveSize)
                {
                    try
                    {
                        await _snapshotStore.BatchSaveAsync(snapshotDataList);
                    }
                    catch (Exception ex)
                    {
                        _logger.Error($"Save snapshot fail:{ex.Message}.", ex);
                    }
                    finally
                    {
                        snapshotDataList.Clear();
                    }
                }
            }
        }