public void persistent_messages_sent_to_multiple_peers_should_only_be_persisted_for_persistent_ones() { using (MessageId.PauseIdGeneration()) { var message = new FakeEvent(123).ToTransportMessage(Self); Transport.Send(message, new[] { AnotherPersistentPeer, AnotherNonPersistentPeer }); InnerTransport.ExpectExactly(new [] { new TransportMessageSent(message).To(AnotherPersistentPeer, true).To(AnotherNonPersistentPeer, false).ToPersistence(PersistencePeer), }); } }
public void should_send_persistent_message_to_the_persistence_and_to_the_peer() { using (MessageId.PauseIdGeneration()) { var message = new FakeCommand(123).ToTransportMessage(); Transport.Send(message, new[] { AnotherPersistentPeer }); InnerTransport.ExpectExactly(new[] { new TransportMessageSent(message).To(AnotherPersistentPeer, true).ToPersistence(PersistencePeer), }); } }
public void should_stop_to_deduplicate_after_safety_phase() { Transport.Start(); var duplicatedMessage = new FakeCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(new SafetyPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(duplicatedMessage); InnerTransport.RaiseMessageReceived(duplicatedMessage); Wait.Until(() => MessagesForwardedToBus.Count == 2, 100.Milliseconds()); MessagesForwardedToBus.ForEach(msg => msg.Id.ShouldEqual(duplicatedMessage.Id)); }
public void should_publish_a_MessageHandled_event_after_a_persistent_message_is_processed_by_the_bus() { Transport.Start(); using (MessageId.PauseIdGeneration()) { var command = new FakeCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(command); Transport.AckMessage(command); InnerTransport.ExpectExactly(new TransportMessageSent(new MessageHandled(command.Id).ToTransportMessage(Self), new[] { PersistencePeer })); } }
public void should_not_lose_messages_when_persistent_transport_goes_down_and_comes_back_up() { using (MessageId.PauseIdGeneration()) { PeerDirectory.Setup(directory => directory.GetPeersHandlingMessage(new MessageBinding(new MessageTypeId(typeof(PersistMessageCommand)), BindingKey.Empty))) .Returns(new List <Peer> { PersistencePeer }); // Stopping persistence InnerTransport.RaiseMessageReceived(new TransportMessage(MessageTypeId.PersistenceStopping, new byte[0], PersistencePeer)); InnerTransport.ExpectExactly(new TransportMessageSent(new TransportMessage(MessageTypeId.PersistenceStoppingAck, new byte[0], Self), PersistencePeer)); InnerTransport.Messages.Clear(); // should enqueue messages to persistence var message = new FakeCommand(123).ToTransportMessage(); var ackedMessage = new FakeCommand(456).ToTransportMessage(); Transport.Send(message, new[] { AnotherPersistentPeer }); Transport.AckMessage(ackedMessage); InnerTransport.AckedMessages.ShouldBeEmpty(); InnerTransport.ExpectExactly(new TransportMessageSent(message, AnotherPersistentPeer)); InnerTransport.Messages.Clear(); // starting persistence - should send enqueued messages Transport.OnPeerUpdated(PersistencePeer.Id, PeerUpdateAction.Started); InnerTransport.ExpectExactly(new[] { new TransportMessageSent(new PersistMessageCommand(message, new[] { AnotherPersistentPeer.Id }).ToTransportMessage(Self), PersistencePeer), new TransportMessageSent(new MessageHandled(ackedMessage.Id).ToTransportMessage(Self), PersistencePeer) }); InnerTransport.Messages.Clear(); InnerTransport.AckedMessages.Clear(); // should send messages without going through the queue Transport.Send(message, new[] { AnotherPersistentPeer }); Transport.AckMessage(ackedMessage); InnerTransport.ExpectExactly(new[] { new TransportMessageSent(message, AnotherPersistentPeer), new TransportMessageSent(new PersistMessageCommand(message, new[] { AnotherPersistentPeer.Id }).ToTransportMessage(Self), PersistencePeer), new TransportMessageSent(new MessageHandled(ackedMessage.Id).ToTransportMessage(Self), PersistencePeer), }); } }
public void should_not_handle_twice_duplicate_messages() { Transport.Start(); var duplicatedMessage = new FakeCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(duplicatedMessage); InnerTransport.RaiseMessageReceived(duplicatedMessage.ToReplayedTransportMessage(StartMessageReplayCommand.ReplayId)); Wait.Until(() => MessagesForwardedToBus.Count == 1, 150.Milliseconds()); MessagesForwardedToBus.Single().Id.ShouldEqual(duplicatedMessage.Id); }
public void should_only_forward_replayed_messages_during_replay_phase() { Transport.Start(); var transportMessageToForward = new FakeCommand(123).ToTransportMessage(); var normalTransportMessage = new FakeEvent(123).ToTransportMessage(); var replayedTransportMessage = transportMessageToForward.ToReplayedTransportMessage(ReplayId); InnerTransport.RaiseMessageReceived(replayedTransportMessage); InnerTransport.RaiseMessageReceived(normalTransportMessage); MessagesForwardedToBus.Count.ShouldEqual(1); MessagesForwardedToBus.Single().Id.ShouldEqual(transportMessageToForward.Id); }
public void should_forward_normal_message_after_replay_phase() { Transport.Start(); var message = new FakeCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); Thread.Sleep(10); InnerTransport.RaiseMessageReceived(message); Thread.Sleep(10); MessagesForwardedToBus.Count.ShouldEqual(1); MessagesForwardedToBus.Single().Id.ShouldEqual(message.Id); }
public void should_send_persistent_message_to_persistence_peer_and_to_the_peer() { using (MessageId.PauseIdGeneration()) { var message = new FakeCommand(123).ToTransportMessage(); Transport.Send(message, new[] { AnotherPersistentPeer }); InnerTransport.ExpectExactly( new TransportMessageSent(message, new[] { AnotherPersistentPeer }), new TransportMessageSent(new PersistMessageCommand(message, new[] { AnotherPersistentPeer.Id }).ToTransportMessage(Self), new[] { PersistencePeer }) ); } }
public void persistent_messages_sent_to_multiple_peers_should_only_be_persisted_for_persistent_ones() { using (MessageId.PauseIdGeneration()) { var message = new FakeEvent(123).ToTransportMessage(Self); var persistCommand = new PersistMessageCommand(message, new[] { AnotherPersistentPeer.Id }).ToTransportMessage(Self); Transport.Send(message, new[] { AnotherPersistentPeer, AnotherNonPersistentPeer }); InnerTransport.ExpectExactly( new TransportMessageSent(message, new[] { AnotherPersistentPeer, AnotherNonPersistentPeer }), new TransportMessageSent(persistCommand, new[] { PersistencePeer }) ); } }
public void should_not_publish_a_MessageHandled_event_after_a_non_persistent_message_is_processed_by_the_bus() { Transport.Start(); using (MessageId.PauseIdGeneration()) { var command = new FakeNonPersistentCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(command); Transport.AckMessage(command); InnerTransport.ExpectNothing(); } }
public void should_forward_a_normal_message_after_a_back_to_live_event() { Transport.Start(); var transportMessageToForward = new FakeCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(transportMessageToForward); MessagesForwardedToBus.ShouldBeEmpty(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); Thread.Sleep(50); MessagesForwardedToBus.Count.ShouldEqual(1); MessagesForwardedToBus.Single().ShouldEqualDeeply(transportMessageToForward); }
public void should_force_WasPersisted_for_replayed_messages() { Transport.Start(); var sourceTransportMessage = new FakeCommand(123).ToTransportMessage(); sourceTransportMessage.WasPersisted = null; var replayTransportMessage = sourceTransportMessage.ToReplayedTransportMessage(ReplayId); InnerTransport.RaiseMessageReceived(replayTransportMessage); var forwardedTransportMessage = MessagesForwardedToBus.ExpectedSingle(); forwardedTransportMessage.WasPersisted.ShouldEqual(true); }
public void should_prioritize_infrastructure_messages() { Transport.Start(); Transport.MessageReceived += x => { Thread.Sleep(200); }; InnerTransport.RaiseMessageReceived(new FakeCommand(1).ToTransportMessage()); InnerTransport.RaiseMessageReceived(new FakeInfrastructureCommand().ToTransportMessage()); Thread.Sleep(20); MessagesForwardedToBus.ShouldContain(x => x.MessageTypeId == new MessageTypeId(typeof(FakeInfrastructureCommand))); Transport.Stop(); }
public void should_forward_a_normal_message_after_a_back_to_live_event() { Transport.Start(); var transportMessageToForward = new FakeCommand(123).ToTransportMessage(); InnerTransport.RaiseMessageReceived(transportMessageToForward); MessagesForwardedToBus.ShouldBeEmpty(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); Wait.Until(() => MessagesForwardedToBus.Count == 1, 150.Milliseconds()); var transportMessage = MessagesForwardedToBus.Single(); transportMessage.ShouldEqualDeeply(transportMessageToForward); }
public void should_not_lose_messages_when_switching_to_safety_phase() { Transport.Start(); var liveMessageToStack = new FakeCommand(123).ToTransportMessage(); var replayedMessageToPlayAfterStack = new FakeCommand(456).ToTransportMessage(); InnerTransport.RaiseMessageReceived(liveMessageToStack); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(replayedMessageToPlayAfterStack.ToReplayedTransportMessage(StartMessageReplayCommand.ReplayId)); Wait.Until(() => MessagesForwardedToBus.Count >= 2, 150.Milliseconds()); MessagesForwardedToBus.Count.ShouldEqual(2); MessagesForwardedToBus.First().Id.ShouldEqual(liveMessageToStack.Id); MessagesForwardedToBus.Last().Id.ShouldEqual(replayedMessageToPlayAfterStack.Id); }
public override async Task FlushAsync(CancellationToken cancellationToken) { CheckNotDisposed(); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } if (WriteBuffer.Length > 0) { WriteBuffer.TryGetBuffer(out ArraySegment <byte> bufSegment); await InnerTransport.WriteAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); WriteBuffer.SetLength(0); } await InnerTransport.FlushAsync(cancellationToken); }
public void should_not_lose_messages_when_persistent_transport_goes_down_and_comes_back_up() { using (MessageId.PauseIdGeneration()) { // Stopping persistence InnerTransport.RaiseMessageReceived(new TransportMessage(MessageTypeId.PersistenceStopping, new MemoryStream(), PersistencePeer)); InnerTransport.ExpectExactly(new TransportMessageSent(new TransportMessage(MessageTypeId.PersistenceStoppingAck, new MemoryStream(), Self), PersistencePeer)); InnerTransport.Messages.Clear(); // should enqueue messages to persistence var message = new FakeCommand(123).ToTransportMessage(); var ackedMessage = new FakeCommand(456).ToTransportMessage(); Transport.Send(message, new[] { AnotherPersistentPeer }); Transport.AckMessage(ackedMessage); InnerTransport.AckedMessages.ShouldBeEmpty(); InnerTransport.ExpectExactly(new TransportMessageSent(message, AnotherPersistentPeer, true)); InnerTransport.Messages.Clear(); // starting persistence - should send enqueued messages Transport.OnPeerUpdated(PersistencePeer.Id, PeerUpdateAction.Started); InnerTransport.ExpectExactly(new[] { new TransportMessageSent(message.ToPersistTransportMessage(AnotherPersistentPeer.Id), PersistencePeer), new TransportMessageSent(new MessageHandled(ackedMessage.Id).ToTransportMessage(Self), PersistencePeer) }); InnerTransport.Messages.Clear(); InnerTransport.AckedMessages.Clear(); // should send messages without going through the queue Transport.Send(message, new[] { AnotherPersistentPeer }); Transport.AckMessage(ackedMessage); InnerTransport.ExpectExactly(new[] { new TransportMessageSent(message, AnotherPersistentPeer, true).ToPersistence(PersistencePeer), new TransportMessageSent(new MessageHandled(ackedMessage.Id).ToTransportMessage(Self), PersistencePeer), }); } }
private async ValueTask ReadFrameAsync(CancellationToken cancellationToken) { UpdateKnownMessageSize(-1); await InnerTransport.ReadAllAsync(HeaderBuf, 0, HeaderSize, cancellationToken); int size = BinaryPrimitives.ReadInt32BigEndian(HeaderBuf); if ((0 > size) || (size > Configuration.MaxFrameSize)) // size must be in the range 0 to allowed max { throw new TTransportException(TTransportException.ExceptionType.Unknown, $"Maximum frame size exceeded ({size} bytes)"); } UpdateKnownMessageSize(size + HeaderSize); ReadBuffer.SetLength(size); ReadBuffer.Seek(0, SeekOrigin.Begin); ReadBuffer.TryGetBuffer(out ArraySegment <byte> bufSegment); await InnerTransport.ReadAllAsync(bufSegment.Array, 0, size, cancellationToken); }
public void should_force_WasPersisted_for_replayed_messages_during_safety_phase() { Transport.Start(); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(ReplayId).ToTransportMessage()); var sourceTransportMessage = new FakeCommand(123).ToTransportMessage(); sourceTransportMessage.WasPersisted = null; var replayTransportMessage = sourceTransportMessage.ToReplayedTransportMessage(ReplayId); InnerTransport.RaiseMessageReceived(replayTransportMessage); Wait.Until(() => MessagesForwardedToBus.Count == 1, 150.Milliseconds()); var forwardedTransportMessage = MessagesForwardedToBus.ExpectedSingle(); forwardedTransportMessage.WasPersisted.ShouldEqual(true); }
public void should_consider_WasPersisted_before_publishing_a_MessageHandled_event(bool wasPersisted) { Transport.Start(); using (MessageId.PauseIdGeneration()) { var command = new FakeCommand(123).ToTransportMessage(wasPersisted: wasPersisted); InnerTransport.RaiseMessageReceived(new ReplayPhaseEnded(StartMessageReplayCommand.ReplayId).ToTransportMessage()); InnerTransport.RaiseMessageReceived(command); Transport.AckMessage(command); if (wasPersisted) { InnerTransport.ExpectExactly(new TransportMessageSent(new MessageHandled(command.Id).ToTransportMessage(Self), PersistencePeer)); } else { InnerTransport.ExpectNothing(); } } }
public void should_discard_messages_waiting_for_persistence_on_stop() { using (MessageId.PauseIdGeneration()) { Transport.Start(); PeerDirectory.Setup(directory => directory.GetPeersHandlingMessage(new MessageBinding(MessageTypeId.PersistenceStoppingAck, BindingKey.Empty))) .Returns(new List <Peer> { PersistencePeer }); // Stopping persistence InnerTransport.RaiseMessageReceived(new TransportMessage(MessageTypeId.PersistenceStopping, new byte[0], PersistencePeer)); InnerTransport.Messages.Clear(); var ackedMessage = new FakeCommand(456).ToTransportMessage(); Transport.AckMessage(ackedMessage); Transport.Stop(); Transport.Start(); } }
public override async ValueTask <int> ReadAsync(byte[] buffer, int offset, int length, CancellationToken cancellationToken) { CheckNotDisposed(); ValidateBufferArgs(buffer, offset, length); if (!IsOpen) { throw new TTransportException(TTransportException.ExceptionType.NotOpen); } // do we have something buffered? var count = ReadBuffer.Length - ReadBuffer.Position; if (count > 0) { return(await ReadBuffer.ReadAsync(buffer, offset, length, cancellationToken)); } // does the request even fit into the buffer? // Note we test for >= instead of > to avoid nonsense buffering if (length >= ReadBuffer.Capacity) { return(await InnerTransport.ReadAsync(buffer, offset, length, cancellationToken)); } // buffer a new chunk of bytes from the underlying transport ReadBuffer.Length = ReadBuffer.Capacity; ArraySegment <byte> bufSegment; ReadBuffer.TryGetBuffer(out bufSegment); ReadBuffer.Length = await InnerTransport.ReadAsync(bufSegment.Array, 0, bufSegment.Count, cancellationToken); ReadBuffer.Position = 0; // deliver the bytes return(await ReadBuffer.ReadAsync(buffer, offset, length, cancellationToken)); }
public override void Close() { CheckNotDisposed(); InnerTransport.Close(); }
public override async Task OpenAsync(CancellationToken cancellationToken) { CheckNotDisposed(); await InnerTransport.OpenAsync(cancellationToken); }