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)); }
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)); }
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); }
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); }
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); }
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); }
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); }
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)); }
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)); }
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); } }
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(); }