async Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable <EventData> events, UserCredentials userCredentials)
        {
// ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source    = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
            var operation = new TransactionalWriteOperation(Settings.Log, source, Settings.RequireMaster,
                                                            transaction.TransactionId, events, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            await source.Task.ConfigureAwait(false);

// ReSharper restore PossibleMultipleEnumeration
        }
Example #2
0
        public Task <WriteResult> CommitTransactionAsync(EventStoreTransaction transaction, UserCredentials userCredentials = null)
        {
            var source = new TaskCompletionSource <WriteResult>();

            var envelope = new EmbeddedResponseEnvelope(
                new EmbeddedResponders.TransactionCommit(source));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(
                _authenticationProvider, GetUserCredentials(_settings, userCredentials), source.SetException,
                user => new ClientMessage.TransactionCommit(corrId, corrId, envelope, false,
                                                            transaction.TransactionId, user));

            return(source.Task);
        }
Example #3
0
        private Task WriteEventsInTransactionalWay(string stream, int eventCount, Func <int, EventData> createEvent)
        {
            Log.Information("Starting to write {eventCount} events to [{stream}] (in single transaction)", eventCount, stream);

            var resSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);
            var store     = GetConnection();

            Action <Task> fail = prevTask => {
                Log.Information("WriteEventsInTransactionalWay for stream {stream} failed.", stream);
                resSource.SetException(prevTask.Exception);
            };

            int writtenCount = 0;
            EventStoreTransaction transaction = null;

            Action <Task> writeTransactionEvent = null;

            writeTransactionEvent = prevTask => {
                if (writtenCount == eventCount)
                {
                    var commitTask = transaction.CommitAsync();
                    commitTask.ContinueWith(fail, TaskContinuationOptions.OnlyOnFaulted);
                    commitTask.ContinueWith(t => {
                        Log.Information("Wrote {eventCount} events to [{stream}] (in single transaction)", eventCount, stream);
                        resSource.SetResult(null);
                    }, TaskContinuationOptions.OnlyOnRanToCompletion);
                    return;
                }

                var writeTask = transaction.WriteAsync(createEvent(writtenCount));

                writtenCount += 1;

                writeTask.ContinueWith(fail, TaskContinuationOptions.OnlyOnFaulted);
                writeTask.ContinueWith(writeTransactionEvent, TaskContinuationOptions.OnlyOnRanToCompletion);
            };

            var startTask = store.StartTransactionAsync(stream, -1);

            startTask.ContinueWith(fail, TaskContinuationOptions.OnlyOnFaulted);
            startTask.ContinueWith(t => {
                transaction = t.Result;
                writeTransactionEvent(t);
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            return(resSource.Task);
        }
        public async Task Dispose_ShouldRollbackAndDisposeAllPendingTransaction()
        {
            var wrappedTransactionMocks = new List <Mock <IWrappedTransaction> >();

            var createTransactionMock = new Mock <Func <IEventStoreConnection, string, long, Task <IWrappedTransaction> > >();

            createTransactionMock
            .Setup(x => x(_eventStoreConnectionMock.Object, "some_id", 0))
            .ReturnsAsync(() =>
            {
                var wrappedTransactionMock = new Mock <IWrappedTransaction>();
                wrappedTransactionMocks.Add(wrappedTransactionMock);
                return(wrappedTransactionMock.Object);
            });

            var transaction = new EventStoreTransaction <string, object>(
                connection: _eventStoreConnectionMock.Object,
                jsonSerializerSettings: _jsonSerializerSettings,
                createTransaction: createTransactionMock.Object);

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            wrappedTransactionMocks.Should().HaveCount(3);
            wrappedTransactionMocks[0].Verify(x => x.Rollback(), Times.Never);
            wrappedTransactionMocks[1].Verify(x => x.Rollback(), Times.Never);
            wrappedTransactionMocks[2].Verify(x => x.Rollback(), Times.Never);

            transaction.Dispose();

            wrappedTransactionMocks[0].Verify(x => x.CommitAsync(), Times.Never);
            wrappedTransactionMocks[1].Verify(x => x.CommitAsync(), Times.Never);
            wrappedTransactionMocks[2].Verify(x => x.CommitAsync(), Times.Never);

            wrappedTransactionMocks[0].Verify(x => x.Rollback(), Times.Once);
            wrappedTransactionMocks[1].Verify(x => x.Rollback(), Times.Once);
            wrappedTransactionMocks[2].Verify(x => x.Rollback(), Times.Once);

            wrappedTransactionMocks[0].Verify(x => x.Dispose(), Times.Once);
            wrappedTransactionMocks[1].Verify(x => x.Dispose(), Times.Once);
            wrappedTransactionMocks[2].Verify(x => x.Dispose(), Times.Once);
        }
        Task <WriteResult> IEventStoreTransactionConnection.CommitTransactionAsync(EventStoreTransaction transaction,
                                                                                   UserCredentials userCredentials)
        {
            Ensure.NotNull(transaction, "transaction");

            var source = new TaskCompletionSource <WriteResult>(TaskCreationOptions.RunContinuationsAsynchronously);

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionCommit(source));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(_authenticationProvider,
                                                 GetUserCredentials(_settings, userCredentials), source.SetException, user =>
                                                 new ClientMessage.TransactionCommit(corrId, corrId, envelope,
                                                                                     false, transaction.TransactionId, user));

            return(source.Task);
        }
        public Task TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable <EventData> events,
                                            UserCredentials userCredentials = null)
        {
            var source =
                new TaskCompletionSource <EventStoreTransaction>(TaskCreationOptions.RunContinuationsAsynchronously);

            var envelope = new EmbeddedResponseEnvelope(
                new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(_authenticationProvider,
                                                 GetUserCredentials(_settings, userCredentials), source.SetException, user =>
                                                 new ClientMessage.TransactionWrite(corrId, corrId, envelope, false,
                                                                                    transaction.TransactionId, events.ConvertToEvents(), user));

            return(source.Task);
        }
Example #7
0
        Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable <EventData> events, UserCredentials userCredentials)
        {
            // ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source = new TaskCompletionSource <EventStoreTransaction>();

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            _publisher.Publish(new ClientMessage.TransactionWrite(corrId, corrId, envelope,
                                                                  false, transaction.TransactionId, events.ConvertToEvents(), SystemAccount.Principal));

            return(source.Task);

            // ReSharper restore PossibleMultipleEnumeration
        }
Example #8
0
        Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable <EventData> events, UserCredentials userCredentials)
        {
            // ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source = new TaskCompletionSource <EventStoreTransaction>(TaskCreationOptions.RunContinuationsAsynchronously);

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(_authenticationProvider, GetUserCredentials(_settings, userCredentials), source.SetException, user => new ClientMessage.TransactionWrite(corrId, corrId, envelope,
                                                                                                                                                                                          false, transaction.TransactionId, events.ConvertToEvents(), user));

            return(source.Task);

            // ReSharper restore PossibleMultipleEnumeration
        }
Example #9
0
        void SaveEventsInBatch(string stream_name, int expected_version,
                               IEnumerable <Event> events, IEventSerializer serializer)
        {
            EventStoreTransaction trasaction = connection_
                                               .StartTransaction(stream_name, expected_version);

            EventData[] serialized_events = Serialize(events, serializer).ToArray();

            int position = 0;

            while (position < serialized_events.Length)
            {
                var page_events = serialized_events
                                  .Skip(position)
                                  .Take(kWritePageSize);
                trasaction.Write(page_events);
                position += kWritePageSize;
            }
            trasaction.Commit();
        }
        private Task <object> CommitTransaction(EventStoreTransaction transaction)
        {
            var resSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            Action <Task> fail = prevTask => {
                Log.Info("WriteEventsInTransactionalWay for transaction {transactionId} failed",
                         transaction.TransactionId);
                resSource.SetException(prevTask.Exception);
            };

            var commitTask = transaction.CommitAsync();

            commitTask.ContinueWith(fail, TaskContinuationOptions.OnlyOnFaulted);
            commitTask.ContinueWith(t => {
                Log.Info("Committed transaction {transactionId}", transaction.TransactionId);
                resSource.SetResult(null);
            }, TaskContinuationOptions.OnlyOnRanToCompletion);

            return(resSource.Task);
        }
        public async Task StoreEvents_ShouldCreateAPendingTransactionForEachCall()
        {
            var createTransactionMock = new Mock <Func <IEventStoreConnection, string, long, Task <IWrappedTransaction> > >();

            createTransactionMock
            .Setup(x => x(_eventStoreConnectionMock.Object, "some_id", 0))
            .ReturnsAsync(new Mock <IWrappedTransaction>().Object);

            var transaction = new EventStoreTransaction <string, object>(
                connection: _eventStoreConnectionMock.Object,
                jsonSerializerSettings: _jsonSerializerSettings,
                createTransaction: createTransactionMock.Object);

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            createTransactionMock.Verify(x => x(It.IsAny <IEventStoreConnection>(), It.IsAny <string>(), It.IsAny <long>()), Times.Once);

            await transaction.StoreEvents("some_id", 1, new object[] { new EventA(), new EventB() });

            createTransactionMock.Verify(x => x(It.IsAny <IEventStoreConnection>(), It.IsAny <string>(), It.IsAny <long>()), Times.Exactly(2));
        }
        private Task <object> WriteTransactionData(EventStoreTransaction transaction, int startingVersion,
                                                   int eventCount, Func <int, EventData> createEvent)
        {
            Log.Info("Starting to write {eventCount} events in transaction {transactionId}", eventCount,
                     transaction.TransactionId);

            var resSource = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            Action <Task> fail = prevTask => {
                Log.Info("WriteEventsInTransactionalWay for transaction {transactionId} failed.",
                         transaction.TransactionId);
                resSource.SetException(prevTask.Exception);
            };

            int version = startingVersion;

            Action <Task> writeTransactionEvent = null;

            writeTransactionEvent = _ => {
                if (version == startingVersion + eventCount)
                {
                    resSource.SetResult(null);
                    return;
                }

                version += 1;

                var writeTask = transaction.WriteAsync(new[] { createEvent(version) });
                writeTask.ContinueWith(fail, TaskContinuationOptions.OnlyOnFaulted);
                writeTask.ContinueWith(writeTransactionEvent, TaskContinuationOptions.OnlyOnRanToCompletion);
            };

            Task.Factory.StartNew(() => writeTransactionEvent(null));

            return(resSource.Task);
        }
        Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable<EventData> events, UserCredentials userCredentials)
        {
            // ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source = new TaskCompletionSource<EventStoreTransaction>();

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            _publisher.Publish(new ClientMessage.TransactionWrite(corrId, corrId, envelope,
                false, transaction.TransactionId, events.ConvertToEvents(), SystemAccount.Principal));

            return source.Task;

            // ReSharper restore PossibleMultipleEnumeration
        }
Example #14
0
 public OngoingTransaction(EventStoreTransaction transaction)
 {
     _transaction = transaction;
 }
        public Task<WriteResult> CommitTransactionAsync(EventStoreTransaction transaction, UserCredentials userCredentials = null)
        {
            var source = new TaskCompletionSource<WriteResult>();

            var envelope = new EmbeddedResponseEnvelope(
                new EmbeddedResponders.TransactionCommit(source));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(
                _authenticationProvider, GetUserCredentials(_settings, userCredentials), source.SetException,
                user => new ClientMessage.TransactionCommit(corrId, corrId, envelope, false,
                    transaction.TransactionId, user));

            return source.Task;
        }
        public Task TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable<EventData> events,
            UserCredentials userCredentials = null)
        {
            var source = new TaskCompletionSource<EventStoreTransaction>();

            var envelope = new EmbeddedResponseEnvelope(
                new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(_authenticationProvider, GetUserCredentials(_settings, userCredentials), source.SetException, user => new ClientMessage.TransactionWrite(corrId, corrId, envelope, false, 
                transaction.TransactionId, events.ConvertToEvents(), user));
            
            return source.Task;
        }
        Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable<EventData> events, UserCredentials userCredentials)
        {
            // ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source = new TaskCompletionSource<EventStoreTransaction>();

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            _publisher.PublishWithAuthentication(_authenticationProvider, GetUserCredentials(_settings, userCredentials), source.SetException, user => new ClientMessage.TransactionWrite(corrId, corrId, envelope,
                false, transaction.TransactionId, events.ConvertToEvents(), user));

            return source.Task;

            // ReSharper restore PossibleMultipleEnumeration
        }
        public Task<WriteResult> CommitTransactionAsync(EventStoreTransaction transaction, UserCredentials userCredentials = null)
        {
            var source = new TaskCompletionSource<WriteResult>();

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionCommit(source));

            Guid corrId = Guid.NewGuid();

            var message = new ClientMessage.TransactionCommit(corrId, corrId, envelope, false,
                transaction.TransactionId, SystemAccount.Principal);

            _publisher.Publish(message);

            return source.Task;
            
        }
        public Task TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable<EventData> events,
            UserCredentials userCredentials = null)
        {
            var source = new TaskCompletionSource<EventStoreTransaction>();

            var envelope = new EmbeddedResponseEnvelope(new EmbeddedResponders.TransactionWrite(source, this));

            Guid corrId = Guid.NewGuid();

            var message = new ClientMessage.TransactionWrite(corrId, corrId, envelope,false, 
                transaction.TransactionId, events.ConvertToEvents(), SystemAccount.Principal);

            _publisher.Publish(message);

            return source.Task;
            
        }
Example #20
0
        private async Task <long> DoWrite(string stream, IEnumerable <EventData> events, long?expectedVersion = null)
        {
            var bucket = Math.Abs(stream.GetHashCode() % _clients.Count());

            long nextVersion;

            using (var ctx = WriteTime.NewContext())
            {
                EventStoreTransaction transaction = null;
                try
                {
                    if (events.Count() > _readsize)
                    {
                        transaction = await _clients[bucket].StartTransactionAsync(stream, expectedVersion ?? ExpectedVersion.Any).ConfigureAwait(false);
                    }

                    if (transaction != null)
                    {
                        Logger.Write(LogLevel.Debug, () => $"Using transaction {events.Count()} is over max {_readsize} to write stream id [{stream}]");
                        var page = 0;
                        while (page < events.Count())
                        {
                            await transaction.WriteAsync(events.Skip(page).Take(_readsize)).ConfigureAwait(false);

                            page += _readsize;
                        }
                        var result = await transaction.CommitAsync().ConfigureAwait(false);

                        nextVersion = result.NextExpectedVersion;
                    }
                    else
                    {
                        var result = await
                                     _clients[bucket].AppendToStreamAsync(stream, expectedVersion ?? ExpectedVersion.Any, events)
                                     .ConfigureAwait(false);

                        nextVersion = result.NextExpectedVersion;
                    }
                }
                catch (WrongExpectedVersionException e)
                {
                    transaction?.Rollback();
                    throw new VersionException($"We expected version {expectedVersion ?? ExpectedVersion.Any}", e);
                }
                catch (CannotEstablishConnectionException e)
                {
                    transaction?.Rollback();
                    throw new PersistenceException(e.Message, e);
                }
                catch (OperationTimedOutException e)
                {
                    transaction?.Rollback();
                    throw new PersistenceException(e.Message, e);
                }
                catch (EventStoreConnectionException e)
                {
                    transaction?.Rollback();
                    throw new PersistenceException(e.Message, e);
                }

                WrittenEvents.Update(events.Count());
                WrittenEventsSize.Update(events.Sum(x => x.Data.Length));
                if (ctx.Elapsed > TimeSpan.FromSeconds(1))
                {
                    SlowLogger.Write(LogLevel.Warn, () => $"Writing {events.Count()} events of total size {events.Sum(x => x.Data.Length)} to stream [{stream}] version {expectedVersion} took {ctx.Elapsed.TotalSeconds} seconds!");
                }
                Logger.Write(LogLevel.Debug, () => $"Writing {events.Count()} events of total size {events.Sum(x => x.Data.Length)} to stream [{stream}] version {expectedVersion} took {ctx.Elapsed.TotalMilliseconds} ms");
            }
            return(nextVersion);
        }
        Task<WriteResult> IEventStoreTransactionConnection.CommitTransactionAsync(EventStoreTransaction transaction, UserCredentials userCredentials)
        {
            Ensure.NotNull(transaction, "transaction");

            var source = new TaskCompletionSource<WriteResult>();
            EnqueueOperation(new CommitTransactionOperation(_settings.Log, source, _settings.RequireMaster, 
                                                            transaction.TransactionId, userCredentials));
            return source.Task;
        }
        Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction, IEnumerable<EventData> events, UserCredentials userCredentials)
        {
// ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source = new TaskCompletionSource<object>();
            EnqueueOperation(new TransactionalWriteOperation(_settings.Log, source, _settings.RequireMaster, 
                                                             transaction.TransactionId, events, userCredentials));
            return source.Task;
// ReSharper restore PossibleMultipleEnumeration
        }
        async Task <WriteResult> IEventStoreTransactionConnection.CommitTransactionAsync(EventStoreTransaction transaction, UserCredentials userCredentials)
        {
            Ensure.NotNull(transaction, "transaction");

            var source    = new TaskCompletionSource <WriteResult>(TaskCreationOptions.RunContinuationsAsynchronously);
            var operation = new CommitTransactionOperation(Settings.Log, source, Settings.RequireMaster,
                                                           transaction.TransactionId, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }