public IEnumerable<IStreamedEvent> Load(Guid identity) { FileStream fs; try { fs = new FileStream( _repositoryHierarchy.For(identity, false), FileMode.Open, FileAccess.Read, FileShare.None, 4096, FileOptions.SequentialScan); } catch (FileNotFoundException x) { throw new StreamNotFoundPersistenceException(identity, _repositoryHierarchy.RootPath, x); } catch (DirectoryNotFoundException x) { throw new StreamNotFoundPersistenceException(identity, _repositoryHierarchy.RootPath, x); } catch (DriveNotFoundException x) { throw new StreamNotFoundPersistenceException(identity, _repositoryHierarchy.RootPath, x); } // Note: The FileStream is created separately outside the using{} block because // the C# compiler dislikes using the 'yield return' inside a try..catch block. using (fs) { using (var esw = new EventStreamReader(fs, _eventReader)) { while (esw.HasNext()) yield return esw.Next(); } } }
private EntityCreatedEvent EventStreamRoundTripEvent(EntityCreatedEvent evt) { EventStreamHeader header = new EventStreamHeader(new VectorClock(), new Infrastructure.VectorClock(), Guid.NewGuid(), Guid.NewGuid()); MemoryStream stream = new MemoryStream(); using (EventStreamWriter writer = new EventStreamWriter(stream, header, false)) { writer.WriteEvent(evt); } stream.Seek(0, SeekOrigin.Begin); using (stream) using (EventStreamReader reader = new EventStreamReader(stream)) { while (reader.Read()) { if (reader.ItemType == ItemType.Event) { return((EntityCreatedEvent)reader.CurrentEvent); } } } throw new InvalidOperationException("The event could not be round tripped"); }
public async Task ReadEventsAsync_WhenCursorIsNotEmpty_ReturnsNotEmptyCollectionEvents( EventStreamReader reader) { await reader.ReadEventsAsync(); Assert.NotEmpty(reader.Events); }
private async Task ReadEventStreamAsync(Func <IBinlogEvent, Task> handleEvent, CancellationToken cancellationToken = default) { var eventStreamReader = new EventStreamReader(_databaseProvider.Deserializer); var channel = new EventStreamChannel(eventStreamReader, _channel.Stream, cancellationToken); var timeout = _options.HeartbeatInterval.Add(TimeSpan.FromMilliseconds(TimeoutConstants.Delta)); while (!cancellationToken.IsCancellationRequested) { var packet = await channel.ReadPacketAsync(cancellationToken).WithTimeout(timeout, TimeoutConstants.Message); if (packet is IBinlogEvent binlogEvent) { // We stop replication if client code throws an exception // As a derived database may end up in an inconsistent state. await handleEvent(binlogEvent); // Commit replication state if there is no exception. UpdateGtidPosition(binlogEvent); UpdateBinlogPosition(binlogEvent); } else if (packet is ErrorPacket error) { throw new InvalidOperationException($"Event stream error. {error.ToString()}"); } else if (packet is EndOfFilePacket && !_options.Blocking) { return; } else { throw new InvalidOperationException($"Event stream unexpected error."); } } }
public async Task ReadEventsAsync_EnsureConnectivityStateIsActive( [Frozen] Mock <IEventStoreConnectionState> stateMock, EventStreamReader reader) { await reader.ReadEventsAsync(); stateMock.Verify(self => self.EnsureConnectionIsActive()); }
public async Task <TEntity> GetByIdAsync(TKey id) { var streamId = GenerateStreamId(id); var streamEvents = await EventStreamReader.Read(_connection, streamId, StreamPosition.Start, 200); var domainEvents = DomainEventFactory.Create(streamEvents, _eventTypeResolver); return(AggregateFactory.Create <TEntity>(domainEvents)); }
public async Task ReadEventsAsync_UseMutationPipelineForEachReceivedEvent( [Frozen] Mock <IEventMutationPipeline> pipelineMock, [Frozen] SortedList <StreamVersion, JournaledEvent> receivedEvents, EventStreamReader reader) { await reader.ReadEventsAsync(); pipelineMock.Verify( self => self.Mutate(It.Is <JournaledEvent>(e => receivedEvents.ContainsValue(e))), Times.Exactly(receivedEvents.Count)); }
public void Test_UnknownStatus_ReturnsExceptionPacket() { var reader = new EventStreamReader(null); var payload = new byte[] { 0xFD, 3, 0, 2, 8 }; var exception = Assert.Throws <Exception>(() => reader.ReadPacket(new ReadOnlySequence <byte>(payload))); Assert.Equal("Unknown network stream status", exception.Message); }
public async Task <IEventStreamReader> CreateStreamReaderAsync(string streamName, StreamVersion streamVersion) { Require.NotEmpty(streamName, "streamName"); m_connectionState.EnsureConnectionIsActive(); var reader = new EventStreamReader( streamName: streamName, connectionState: m_connectionState, streamCursor: await m_journal.OpenEventStreamCursorAsync(streamName, streamVersion), mutationPipeline: m_pipelineFactory.CreateIncomingPipeline()); return(reader); }
public async Task ReadEventsAsync_ReplaceReceivedEventsWithTheyMutatedVersion( [Frozen] Mock <IEventMutationPipeline> pipelineMock, JournaledEvent[] mutatedEvents, EventStreamReader reader) { var callsCount = 0; pipelineMock .Setup(self => self.Mutate(It.IsAny <JournaledEvent>())) .Returns(() => mutatedEvents[callsCount++]); await reader.ReadEventsAsync(); Assert.Equal(mutatedEvents.Select(e => e.EventId), reader.Events.Select(e => e.EventId)); }
private void StartEvents(Stream stream, string eventName = null, bool exactMatch = false) { // create an event so reader can signal emitter AutoResetEvent emitterWaitHandle = new AutoResetEvent(true); // instantiate the stream reader and event emitter reader = new EventStreamReader(stream, queue, emitterWaitHandle); emitter = new EventStreamEmitter(queue, this.raiseEvent, emitterWaitHandle, eventName, exactMatch); // start the task reader : stream -> queue taskReader = Task.Factory.StartNew(() => { Thread.CurrentThread.Name = "StreamReader"; reader.DoWork(); }, TaskCreationOptions.LongRunning); // start the task emitter : queue -> events taskEmitter = Task.Factory.StartNew(() => { Thread.CurrentThread.Name = "Event Emitter"; emitter.DoWork(); }, TaskCreationOptions.LongRunning); }
public void Test_EOFStatus_ReturnsEndOfFilePacket() { var reader = new EventStreamReader(null); var payload = new byte[] { 0xFE, 3, 0, 2, 8 }; var packet = reader.ReadPacket(new ReadOnlySequence <byte>(payload)); Assert.IsType <EndOfFilePacket>(packet); var eofPacket = packet as EndOfFilePacket; Assert.Equal(3, eofPacket.WarningCount); Assert.Equal(2 | (8 << 8), eofPacket.ServerStatus); }
/// <summary> /// Replicates binlog events from the server /// </summary> /// <param name="cancellationToken">Cancellation token</param> /// <returns>Task completed when last event is read in non-blocking mode</returns> public async IAsyncEnumerable <IBinlogEvent> Replicate([EnumeratorCancellation] CancellationToken cancellationToken = default) { await ConnectAsync(cancellationToken); // Clear on reconnect _gtid = null; _transaction = false; await AdjustStartingPosition(cancellationToken); await SetMasterHeartbeat(cancellationToken); await SetMasterBinlogChecksum(cancellationToken); await _databaseProvider.DumpBinlogAsync(_channel, _options, cancellationToken); var eventStreamReader = new EventStreamReader(_databaseProvider.Deserializer); var channel = new EventStreamChannel(eventStreamReader, _channel.Stream); var timeout = _options.HeartbeatInterval.Add(TimeSpan.FromMilliseconds(TimeoutConstants.Delta)); await foreach (var packet in channel.ReadPacketAsync(timeout, cancellationToken).WithCancellation(cancellationToken)) { if (packet is IBinlogEvent binlogEvent) { // We stop replication if client code throws an exception // As a derived database may end up in an inconsistent state. yield return(binlogEvent); // Commit replication state if there is no exception. UpdateGtidPosition(binlogEvent); UpdateBinlogPosition(binlogEvent); } else if (packet is EndOfFilePacket && !_options.Blocking) { yield break; } else if (packet is ErrorPacket error) { throw new InvalidOperationException($"Event stream error. {error.ToString()}"); } else { throw new InvalidOperationException($"Event stream unexpected error."); } } }
public void Verify() { _innerStream.Position = 0; using (var esr = new EventStreamReader(_innerStream.PreventClosure(), _eventReader)) { while (_innerStream.Position < _innerStream.Length) { try { esr.Next(); } catch (TruncationVerificationPersistenceException x) { // A trailing commit was unfinished possibly due to power cut or system crash. // This can be repaired easily just by truncating the stream. _innerStream.SetLength(x.Offset); } } } _innerStream.Position = _innerStream.Length; }
public void Test_ErrorStatus_ReturnsErrorPacket() { var reader = new EventStreamReader(null); var payload = new byte[] { 0xFF, 212, 4, 35, 72, 89, 48, 48, 48, 67, 111, 117, 108, 100, 32, 110, 111, 116, 32, 102, 105, 110, 100, 32, 102, 105, 114, 115, 116, 32, 108, 111, 103, 32, 102, 105, 108, 101, 32, 110, 97, 109, 101, 32, 105, 110, 32, 98, 105, 110, 97, 114, 121, 32, 108, 111, 103, 32, 105, 110, 100, 101, 120, 32, 102, 105, 108, 101 }; var packet = reader.ReadPacket(new ReadOnlySequence <byte>(payload)); Assert.IsType <ErrorPacket>(packet); var errorPacket = packet as ErrorPacket; Assert.Equal("HY000", errorPacket.SqlState); Assert.Equal(1236, errorPacket.ErrorCode); Assert.Equal("Could not find first log file name in binary log index file", errorPacket.ErrorMessage); }
public void Test_DeserializationException_ReturnsExceptionPacket() { var reader = new EventStreamReader(new MySqlEventDeserializer() { ChecksumStrategy = new Crc32Checksum() }); var payload = new byte[] { 0, 192, 218, 96, 94, 15, 1, 0, 0, 0, 120, 0, 0, 0, 124, 0, 0, 0, 0, 0, 4, 0, 56, 46, 48, 46, 49, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 218, 96, 94, 19, 0, 13, 0, 8, 0, 0, 0, 0, 4, 0, 4, 0, 0, 0, 96, 0, 4, 26, 8, 0, 0, 0, 8, 8, 8, 2, 0, 0, 0, 10, 10, 10, 42, 42, 0, 18, 52, 0, 10, 5, // We changed checksum type 225, 100, 86, 201 }; var exception = Assert.Throws <InvalidOperationException>(() => reader.ReadPacket(new ReadOnlySequence <byte>(payload))); Assert.Equal("The master checksum type is not supported.", exception.Message); }
public void Test_EventStatus_ReturnsEventPacket() { var reader = new EventStreamReader(new MySqlEventDeserializer() { ChecksumStrategy = new Crc32Checksum() }); var payload = new byte[] { 0x00, 0, 0, 0, 0, 4, 1, 0, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 32, 0, 4, 0, 0, 0, 0, 0, 0, 0, 98, 105, 110, 108, 111, 103, 46, 48, 48, 48, 48, 48, 49, 233, 210, 202, 110 }; var packet = reader.ReadPacket(new ReadOnlySequence <byte>(payload)); Assert.IsType <RotateEvent>(packet); var rotateEvent = packet as RotateEvent; Assert.Equal("binlog.000001", rotateEvent.BinlogFilename); Assert.Equal(4, rotateEvent.BinlogPosition); }
internal PersonRepository() { this.journal = EventJournal.Open("repo-test"); this.reader = this.journal.StreamReader(); }
public async Task ReadEventsAsync_WhenCursorIsEmpty_Throw( EventStreamReader reader) { await Assert.ThrowsAsync <InvalidOperationException>(reader.ReadEventsAsync); }
internal JournalPricingAnalysisRepository() { this.journal = PricingJournal.EventJournal; this.reader = this.journal.StreamReader(); }
public async Task ReadEventsAsync_WhenCursorIsNotEmpty_DoesNotThrow( EventStreamReader reader) { await reader.ReadEventsAsync(); }
public void HasEvents_WhenCursorIsEmpty_ReturnsFalse( EventStreamReader reader) { Assert.False(reader.HasEvents); }
public void HaEvents_WhenCursorIsNotEmpty_ReturnsTrue( EventStreamReader reader) { Assert.True(reader.HasEvents); }
internal JournalProposalRepository() { this.journal = EventJournal.Open("donebyme-matching"); this.reader = this.journal.StreamReader(); }