public async Task StoreSnapshotAsync(string stream, SnapshotDescriptor snapshotDescriptor,
                                             CancellationToken cancellationToken = default)
        {
            if (snapshotDescriptor == null)
            {
                throw new ArgumentException(nameof(snapshotDescriptor));
            }

            var stopWatch = new Stopwatch();

            stopWatch.Start();

            using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                using (var cnx = new SqlConnection(_eventstoreOptions.Value.ConnectionString))
                {
                    cnx.Open();

                    var cmd = new SqlCommand(_scripts.SetSnapshotForStream, cnx);
                    cmd.Parameters.Add(new SqlParameter("@SnapshotType", SqlDbType.VarChar, 300)
                    {
                        Value = snapshotDescriptor.SnapshotType
                    });

                    cmd.Parameters.Add(new SqlParameter("@SnapshotData", SqlDbType.NVarChar, -1)
                    {
                        Value = snapshotDescriptor.SnapshotData
                    });

                    cmd.Parameters.Add(new SqlParameter("@StreamVersion", SqlDbType.Int)
                    {
                        Value = snapshotDescriptor.AggregateVersion
                    });

                    cmd.Parameters.Add(new SqlParameter("@StreamId", SqlDbType.VarChar, 200)
                    {
                        Value = stream
                    });

                    try
                    {
                        await cmd.ExecuteNonQueryAsync(cancellationToken);
                    }
                    catch (SqlException ex) when(ex.Errors[0].Message == "VersionAlreadyExists")
                    {
                        if (snapshotDescriptor.AggregateVersion == 0)
                        {
                            throw new ConcurrencyUnrecoverableException("SnapshotStore unrecoverable concurrency exception", ex);
                        }

                        throw new ConcurrencyException("SnapshotStore concurrency exception", ex);
                    }

                    ts.Complete();
                }

            stopWatch.Stop();
            _logger.LogDebug("AdoNetSnapshotRepository.StoreSnapshotAsync for {Stream} took {ElapsedMilliseconds} ms.",
                             stream, stopWatch.ElapsedMilliseconds);
        }
        public Task StoreSnapshotAsync(string stream, SnapshotDescriptor snapshotDescriptor, CancellationToken cancellationToken = default)
        {
            _storage.AddOrUpdate(stream,
                                 key => snapshotDescriptor,
                                 (key, value) => snapshotDescriptor);

            return(Task.CompletedTask);
        }
        /// <inheritdoc />
        public override async Task SaveSnapshotAsync(ISnapshot snapshot)
        {
            var snapshotDescriptor = new SnapshotDescriptor(this.AggregateType, this.AggregateId, snapshot);

            await this.documentSession.StoreAsync(snapshotDescriptor).ConfigureAwait(false);

            await this.documentSession.SaveChangesAsync().ConfigureAwait(false);
        }
        public async Task <SnapshotDescriptor> LoadSnapshotAsync(string stream, CancellationToken cancellationToken = default)
        {
            var stopWatch = new Stopwatch();

            stopWatch.Start();

            SnapshotDescriptor snapshotDescriptor = null;

            using (var cnx = new SqlConnection(_eventstoreOptions.Value.ConnectionString))
            {
                cnx.Open();

                var cmd = new SqlCommand(_scripts.GetSnapshotForStream, cnx);

                cmd.Parameters.Add(new SqlParameter("@StreamId", SqlDbType.VarChar, 200)
                {
                    Value = stream
                });

                cmd.Parameters.Add(new SqlParameter("@MaxStreamVersion", SqlDbType.Int)
                {
                    Value = DBNull.Value
                });                        // To be implemented for loading aggregate at a specific version

                foreach (var param in GetGlobalFilterParams())
                {
                    cmd.Parameters.Add(param);
                }

                using (var reader = await cmd.ExecuteReaderAsync(cancellationToken))
                {
                    if (reader.Read())
                    {
                        snapshotDescriptor = new SnapshotDescriptor(reader.GetString(0), reader.GetString(1), stream,
                                                                    reader.GetInt32(2));
                    }
                }
            }

            stopWatch.Stop();
            _logger.LogDebug("AdoNetSnapshotRepository.LoadSnapshotAsync for {Stream} took {ElapsedMilliseconds} ms.",
                             stream, stopWatch.ElapsedMilliseconds);

            return(snapshotDescriptor);
        }
Exemple #5
0
        public async Task Should_load_snapshot_in_snapshot_repository()
        {
            //Arrange
            var stream             = "stream";
            var descriptor         = new SnapshotDescriptor("aaa", "", stream, 5);
            var snapshotRepository = new Mock <ISnapshotRepository>();

            snapshotRepository.Setup(x => x.LoadSnapshotAsync(It.IsAny <string>(), It.IsAny <CancellationToken>()))
            .Returns(Task.FromResult(descriptor));

            var eventSerDes = new Mock <IEventStoreSerDes>();
            var sut         = new SnapshotStore(snapshotRepository.Object, eventSerDes.Object, Mock.Of <ILogger <SnapshotStore> >());

            //Act
            var snapshot = await sut.LoadSnapshotAsync(stream, It.IsAny <CancellationToken>());

            //Assert
            snapshotRepository.Verify(er => er.LoadSnapshotAsync(stream, It.IsAny <CancellationToken>()), Times.Once);
        }
Exemple #6
0
 protected ISnapshotRequest CreateFluent(string snapshotName, SnapshotDescriptor d) => d
 .WaitForCompletion()
 .Indices(SnapshotIndexName);