Example #1
0
        protected IPrepareLogRecord <TStreamId> WriteTransactionEnd(Guid correlationId, long transactionId, string eventStreamName)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            GetOrReserve(eventStreamName, out var eventStreamId, out _);
            return(WriteTransactionEnd(correlationId, transactionId, eventStreamId));
        }
Example #2
0
        protected long WriteCommit(Guid correlationId, long transactionId, string eventStreamName, long eventNumber)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            GetOrReserve(eventStreamName, out var eventStreamId, out _);
            return(WriteCommit(correlationId, transactionId, eventStreamId, eventNumber));
        }
        protected EventRecord WriteTransactionEvent(Guid correlationId,
                                                    long transactionPos,
                                                    int transactionOffset,
                                                    string eventStreamName,
                                                    long eventNumber,
                                                    string eventData,
                                                    PrepareFlags flags,
                                                    bool retryOnFail = false)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            _streamNameIndex.GetOrAddId(eventStreamName, out var eventStreamId, out _, out _);

            var prepare = LogRecord.Prepare(_recordFactory, WriterCheckpoint.ReadNonFlushed(),
                                            correlationId,
                                            Guid.NewGuid(),
                                            transactionPos,
                                            transactionOffset,
                                            eventStreamId,
                                            ExpectedVersion.Any,
                                            flags,
                                            "some-type",
                                            Helper.UTF8NoBom.GetBytes(eventData),
                                            null);

            if (retryOnFail)
            {
                long firstPos = prepare.LogPosition;
                long newPos;
                if (!Writer.Write(prepare, out newPos))
                {
                    var tPos = prepare.TransactionPosition == prepare.LogPosition
                                                ? newPos
                                                : prepare.TransactionPosition;
                    prepare = _recordFactory.CopyForRetry(
                        prepare: prepare,
                        logPosition: newPos,
                        transactionPosition: tPos);
                    if (!Writer.Write(prepare, out newPos))
                    {
                        Assert.Fail("Second write try failed when first writing prepare at {0}, then at {1}.", firstPos,
                                    prepare.LogPosition);
                    }
                }

                Assert.AreEqual(eventStreamId, prepare.EventStreamId);
                return(new EventRecord(eventNumber, prepare, eventStreamName));
            }

            long pos;

            Assert.IsTrue(Writer.Write(prepare, out pos));

            Assert.AreEqual(eventStreamId, prepare.EventStreamId);
            return(new EventRecord(eventNumber, prepare, eventStreamName));
        }
Example #4
0
        protected long WriteCommit(Guid correlationId, long transactionId, TStreamId eventStreamId, long eventNumber)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            var  commit = LogRecord.Commit(WriterCheckpoint.ReadNonFlushed(), correlationId, transactionId, eventNumber);
            long pos;

            Assert.IsTrue(Writer.Write(commit, out pos));
            return(commit.LogPosition);
        }
Example #5
0
        protected CommitLogRecord WriteCommit(long preparePos, string eventStreamName, long eventNumber)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            var  commit = LogRecord.Commit(WriterCheckpoint.ReadNonFlushed(), Guid.NewGuid(), preparePos, eventNumber);
            long pos;

            Assert.IsTrue(Writer.Write(commit, out pos));
            return(commit);
        }
Example #6
0
        protected IPrepareLogRecord <TStreamId> WriteTransactionBegin(string eventStreamName, long expectedVersion)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            GetOrReserve(eventStreamName, out var eventStreamId, out var pos);
            var prepare = LogRecord.TransactionBegin(_recordFactory, pos, Guid.NewGuid(), eventStreamId,
                                                     expectedVersion);

            Assert.IsTrue(Writer.Write(prepare, out pos));
            return(prepare);
        }
        public void throw_argumentexception_when_given_empty_eventstreamid()
        {
            var emptyStreamId         = LogFormatHelper <TLogFormat, TStreamId> .EmptyStreamId;
            var expectedExceptionType = LogFormatHelper <TLogFormat, TStreamId> .Choose <Type>(
                typeof(ArgumentNullException),
                typeof(ArgumentOutOfRangeException));

            Assert.Throws(expectedExceptionType, () => {
                LogRecord.Prepare(_recordFactory, 0, Guid.NewGuid(), Guid.NewGuid(), 0, 0, emptyStreamId, 0,
                                  PrepareFlags.None, "type", new byte[0], null, DateTime.UtcNow);
            });
        }
        protected IPrepareLogRecord <TStreamId> WriteTransactionBegin(string eventStreamName, long expectedVersion)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            _streamNameIndex.GetOrAddId(eventStreamName, out var eventStreamId, out _, out _);
            var prepare = LogRecord.TransactionBegin(_recordFactory, WriterCheckpoint.ReadNonFlushed(), Guid.NewGuid(), eventStreamId,
                                                     expectedVersion);
            long pos;

            Assert.IsTrue(Writer.Write(prepare, out pos));
            return(prepare);
        }
Example #9
0
        protected CommitLogRecord WriteDeleteCommit(IPrepareLogRecord prepare)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            long pos;
            var  commit = LogRecord.Commit(WriterCheckpoint.ReadNonFlushed(),
                                           prepare.CorrelationId,
                                           prepare.LogPosition,
                                           EventNumber.DeletedStream);

            Assert.IsTrue(Writer.Write(commit, out pos));

            return(commit);
        }
Example #10
0
        protected IPrepareLogRecord <TStreamId> WriteTransactionEnd(Guid correlationId, long transactionId, TStreamId eventStreamId)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            var prepare = LogRecord.TransactionEnd(_recordFactory, WriterCheckpoint.ReadNonFlushed(),
                                                   correlationId,
                                                   Guid.NewGuid(),
                                                   transactionId,
                                                   eventStreamId);
            long pos;

            Assert.IsTrue(Writer.Write(prepare, out pos));
            return(prepare);
        }
Example #11
0
        private LogRecord CreateLogRecordV0(Rec rec, TransactionInfo transInfo, int transOffset, long logPos,
                                            long expectedVersion, ReadOnlyMemory <byte> data, PrepareFlags flags)
        {
            LogFormatHelper <TLogFormat, TStreamId> .EnsureV0PrepareSupported();

            return(new PrepareLogRecord(logPos,
                                        Guid.NewGuid(),
                                        rec.Id,
                                        transInfo.TransactionPosition,
                                        transOffset,
                                        rec.StreamId,
                                        expectedVersion,
                                        rec.TimeStamp,
                                        flags,
                                        rec.EventType,
                                        data,
                                        null,
                                        LogRecordVersion.LogRecordV0));
        }
Example #12
0
        protected EventRecord WriteTransactionBegin(string eventStreamName, long expectedVersion, long eventNumber,
                                                    string eventData)
        {
            LogFormatHelper <TLogFormat, TStreamId> .CheckIfExplicitTransactionsSupported();

            GetOrReserve(eventStreamName, out var eventStreamId, out var pos);
            var prepare = LogRecord.Prepare(_recordFactory, pos,
                                            Guid.NewGuid(),
                                            Guid.NewGuid(),
                                            WriterCheckpoint.ReadNonFlushed(),
                                            0,
                                            eventStreamId,
                                            expectedVersion,
                                            PrepareFlags.Data | PrepareFlags.TransactionBegin,
                                            "some-type",
                                            Helper.UTF8NoBom.GetBytes(eventData),
                                            null);

            Assert.IsTrue(Writer.Write(prepare, out pos));
            Assert.AreEqual(eventStreamId, prepare.EventStreamId);

            return(new EventRecord(eventNumber, prepare, eventStreamName));
        }
Example #13
0
        public void can_add_epochs_to_cache()
        {
            Assert.That(_cache.Count == 0);
            //add fist epoch to empty cache
            _epochManager.AddEpochToCache(_epochs[3]);

            Assert.That(_cache.Count == 4);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[0].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[3].EpochNumber);

            //add new last epoch
            _epochManager.AddEpochToCache(_epochs[4]);

            Assert.That(_cache.Count == 5);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[0].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[4].EpochNumber);

            //idempotent add
            _epochManager.AddEpochToCache(_epochs[1]);
            _epochManager.AddEpochToCache(_epochs[2]);
            _epochManager.AddEpochToCache(_epochs[3]);

            Assert.That(_cache.Count == 5);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[0].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[4].EpochNumber);

            //add new skip 1 last epoch
            _epochManager.AddEpochToCache(_epochs[6]);

            Assert.That(_cache.Count == 7);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[0].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[6].EpochNumber);

            //add new skip 5 last epoch
            _epochManager.AddEpochToCache(_epochs[11]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[2].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[11].EpochNumber);

            //add last rolls cache
            _epochManager.AddEpochToCache(_epochs[12]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[3].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[12].EpochNumber);


            //add epoch before cache
            _epochManager.AddEpochToCache(_epochs[1]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[3].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[12].EpochNumber);

            //add idempotent first epoch
            _epochManager.AddEpochToCache(_epochs[2]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[3].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[12].EpochNumber);

            //add idempotent last epoch
            _epochManager.AddEpochToCache(_epochs[12]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[3].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[12].EpochNumber);

            //add disjunct skip epoch
            _epochManager.AddEpochToCache(_epochs[24]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);


            //cannot get epoch ahead of last cached on master
            var nextEpoch = _epochManager.GetEpochAfter(_epochs[24].EpochNumber, false);

            Assert.Null(nextEpoch);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);

            //cannot get epoch ahead of cache on master
            nextEpoch = _epochManager.GetEpochAfter(_epochs[25].EpochNumber, false);
            Assert.Null(nextEpoch);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);

            //can get next  in cache
            nextEpoch = _epochManager.GetEpochAfter(_epochs[20].EpochNumber, false);

            Assert.That(nextEpoch.EpochPosition == _epochs[21].EpochPosition);
            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);

            //can get next from first
            nextEpoch = _epochManager.GetEpochAfter(_epochs[15].EpochNumber, false);

            Assert.That(nextEpoch.EpochPosition == _epochs[16].EpochPosition);
            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);

            //can get next epoch from just before cache
            nextEpoch = _epochManager.GetEpochAfter(_epochs[14].EpochNumber, false);

            Assert.That(nextEpoch.EpochPosition == _epochs[15].EpochPosition);
            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);

            //can get next epoch from before cache
            nextEpoch = _epochManager.GetEpochAfter(_epochs[10].EpochNumber, false);

            Assert.That(nextEpoch.EpochPosition == _epochs[11].EpochPosition);
            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);

            //can get next epoch from 0 epoch
            nextEpoch = _epochManager.GetEpochAfter(_epochs[0].EpochNumber, false);

            Assert.That(nextEpoch.EpochPosition == _epochs[1].EpochPosition);
            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[15].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[24].EpochNumber);


            //can add last epoch in log
            _epochManager.AddEpochToCache(_epochs[29]);

            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == _epochs[20].EpochNumber);
            Assert.That(_cache.Last.Value.EpochNumber == _epochs[29].EpochNumber);

            // can write an epoch with epoch information (even though previous epochs
            // dont have epoch information)
            _epochManager.WriteNewEpoch(GetNextEpoch());
            _epochManager.WriteNewEpoch(GetNextEpoch());
            var epochsWritten = _published.OfType <SystemMessage.EpochWritten>().ToArray();

            Assert.AreEqual(2, epochsWritten.Length);
            for (int i = 0; i < epochsWritten.Length; i++)
            {
                _reader.Reposition(epochsWritten[i].Epoch.EpochPosition);
                _reader.TryReadNext();                 // read epoch
                IPrepareLogRecord <TStreamId> epochInfo;
                while (true)
                {
                    var result = _reader.TryReadNext();
                    Assert.True(result.Success);
                    if (result.LogRecord is IPrepareLogRecord <TStreamId> prepare)
                    {
                        epochInfo = prepare;
                        break;
                    }
                }
                var expectedStreamId = LogFormatHelper <TLogFormat, TStreamId> .Choose <TStreamId>(
                    SystemStreams.EpochInformationStream,
                    LogV3SystemStreams.EpochInformationStreamNumber);

                var expectedEventType = LogFormatHelper <TLogFormat, TStreamId> .Choose <TStreamId>(
                    SystemEventTypes.EpochInformation,
                    LogV3SystemEventTypes.EpochInformationNumber);

                Assert.AreEqual(expectedStreamId, epochInfo.EventStreamId);
                Assert.AreEqual(expectedEventType, epochInfo.EventType);
                Assert.AreEqual(i - 1, epochInfo.ExpectedVersion);
                Assert.AreEqual(_instanceId, epochInfo.Data.ParseJson <EpochDto>().LeaderInstanceId);
            }
        }
Example #14
0
        public void can_write_epochs()
        {
            //can write first epoch
            _published.Clear();
            var beforeWrite = DateTime.UtcNow;

            _epochManager.WriteNewEpoch(GetNextEpoch());
            Assert.That(_published.Count == 1);
            var epochWritten = _published[0] as SystemMessage.EpochWritten;

            Assert.NotNull(epochWritten);
            Assert.That(epochWritten.Epoch.EpochNumber == 0);
            Assert.That(epochWritten.Epoch.PrevEpochPosition == -1);
            Assert.That(epochWritten.Epoch.EpochPosition == 0);
            Assert.That(epochWritten.Epoch.LeaderInstanceId == _instanceId);
            Assert.That(epochWritten.Epoch.TimeStamp < DateTime.UtcNow);
            Assert.That(epochWritten.Epoch.TimeStamp >= beforeWrite);

            // will_cache_epochs_written() {

            for (int i = 0; i < 4; i++)
            {
                _epochManager.WriteNewEpoch(GetNextEpoch());
            }
            Assert.That(_cache.Count == 5);
            Assert.That(_cache.First.Value.EpochNumber == 0);
            Assert.That(_cache.Last.Value.EpochNumber == 4);
            var epochs = new List <int>();
            var epoch  = _cache.First;

            while (epoch != null)
            {
                epochs.Add(epoch.Value.EpochNumber);
                epoch = epoch.Next;
            }
            CollectionAssert.IsOrdered(epochs);

            // can_write_more_epochs_than_cache_size

            for (int i = 0; i < 16; i++)
            {
                _epochManager.WriteNewEpoch(GetNextEpoch());
            }
            Assert.That(_cache.Count == 10);
            Assert.That(_cache.First.Value.EpochNumber == 11);
            Assert.That(_cache.Last.Value.EpochNumber == 20);
            epochs = new List <int>();
            epoch  = _cache.First;
            while (epoch != null)
            {
                epochs.Add(epoch.Value.EpochNumber);
                epoch = epoch.Next;
            }
            CollectionAssert.IsOrdered(epochs);

            // has written epoch information
            var epochsWritten = _published.OfType <SystemMessage.EpochWritten>().ToArray();

            Assert.AreEqual(1 + 4 + 16, epochsWritten.Length);
            for (int i = 0; i < epochsWritten.Length; i++)
            {
                _reader.Reposition(epochsWritten[i].Epoch.EpochPosition);
                _reader.TryReadNext();                 // read epoch
                IPrepareLogRecord <TStreamId> epochInfo;
                while (true)
                {
                    var result = _reader.TryReadNext();
                    Assert.True(result.Success);
                    if (result.LogRecord is IPrepareLogRecord <TStreamId> prepare)
                    {
                        epochInfo = prepare;
                        break;
                    }
                }
                var expectedStreamId = LogFormatHelper <TLogFormat, TStreamId> .Choose <TStreamId>(
                    SystemStreams.EpochInformationStream,
                    LogV3SystemStreams.EpochInformationStreamNumber);

                var expectedEventType = LogFormatHelper <TLogFormat, TStreamId> .Choose <TStreamId>(
                    SystemEventTypes.EpochInformation,
                    LogV3SystemEventTypes.EpochInformationNumber);

                Assert.AreEqual(expectedStreamId, epochInfo.EventStreamId);
                Assert.AreEqual(expectedEventType, epochInfo.EventType);
                Assert.AreEqual(i - 1, epochInfo.ExpectedVersion);
                Assert.AreEqual(_instanceId, epochInfo.Data.ParseJson <EpochDto>().LeaderInstanceId);
            }
            _published.Clear();
        }