Exemple #1
0
        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),
                });
            }
        }
Exemple #2
0
        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);
        }
Exemple #14
0
        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();
        }
Exemple #15
0
        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);
        }
Exemple #17
0
        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);
        }
Exemple #18
0
        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),
                });
            }
        }
Exemple #19
0
        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);
        }
Exemple #20
0
        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));
        }
Exemple #24
0
        public override void Close()
        {
            CheckNotDisposed();

            InnerTransport.Close();
        }
Exemple #25
0
        public override async Task OpenAsync(CancellationToken cancellationToken)
        {
            CheckNotDisposed();

            await InnerTransport.OpenAsync(cancellationToken);
        }