private Task <object> WriteTransactionData(EventStoreTransaction transaction, int startingVersion, int eventCount, Func <int, EventData> createEvent)
        {
            Log.Info("Starting to write {0} events in tran {1}", eventCount, transaction.TransactionId);

            var resSource = new TaskCompletionSource <object>();

            Action <Task> fail = prevTask =>
            {
                Log.Info("WriteEventsInTransactionalWay for transaction {0} 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);
        }
Exemple #2
0
        private Task WriteEventsInTransactionalWay(string stream, int eventCount, Func <int, EventData> createEvent)
        {
            Log.Info("Starting to write {0} events to [{1}] (in single transaction)", eventCount, stream);

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

            Action <Task> fail = prevTask =>
            {
                Log.Info("WriteEventsInTransactionalWay for stream {0} 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.Info("Wrote {0} events to [{1}] (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);
        }
Exemple #3
0
        public async Task <OngoingTransaction> Write(params EventData[] events)
        {
            await _transaction.WriteAsync(events);

            return(this);
        }
Exemple #4
0
 public OngoingTransaction Write(params EventData[] events)
 {
     _transaction.WriteAsync(events).Wait();
     return(this);
 }
Exemple #5
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);
        }