示例#1
0
        public void IdleTimeoutBidi_must_signal_error_to_all_outputs()
        {
            this.AssertAllStagesStopped(() =>
            {
                var upWrite = this.CreatePublisherProbe <string>();
                var upRead  = this.CreateSubscriberProbe <int>();

                var downWrite = this.CreatePublisherProbe <int>();
                var downRead  = this.CreateSubscriberProbe <string>();

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var timeoutStage = b.Add(BidiFlow.BidirectionalIdleTimeout <string, int>(TimeSpan.FromSeconds(2)));

                    b.From(Source.FromPublisher(upWrite)).To(timeoutStage.Inlet1);
                    b.From(timeoutStage.Outlet1).To(Sink.FromSubscriber(downRead));
                    b.From(timeoutStage.Outlet2).To(Sink.FromSubscriber(upRead));
                    b.From(Source.FromPublisher(downWrite)).To(timeoutStage.Inlet2);

                    return(ClosedShape.Instance);
                })).Run(Materializer);

                var te = new TestException("test");

                upWrite.SendError(te);

                upRead.ExpectSubscriptionAndError().ShouldBeEquivalentTo(te);
                downRead.ExpectSubscriptionAndError().ShouldBeEquivalentTo(te);
                downWrite.ExpectCancellation();
            }, Materializer);
        }
示例#2
0
        public void IdleTimeoutBidi_must_not_signal_error_if_traffic_is_one_way()
        {
            this.AssertAllStagesStopped(() =>
            {
                var upstreamWriter   = this.CreatePublisherProbe <int>();
                var downstreamWriter = this.CreatePublisherProbe <string>();

                var upstream = Flow.FromSinkAndSource(Sink.Ignore <string>(),
                                                      Source.FromPublisher(upstreamWriter), Keep.Left);
                var downstream = Flow.FromSinkAndSource(Sink.Ignore <int>(),
                                                        Source.FromPublisher(downstreamWriter), Keep.Left);

                var assembly = upstream.JoinMaterialized(
                    BidiFlow.BidirectionalIdleTimeout <int, string>(TimeSpan.FromSeconds(2)),
                    Keep.Left).JoinMaterialized(downstream, Keep.Both);
                var r            = assembly.Run(Materializer);
                var upFinished   = r.Item1;
                var downFinished = r.Item2;

                upstreamWriter.SendNext(1);
                Thread.Sleep(1000);
                upstreamWriter.SendNext(1);
                Thread.Sleep(1000);
                upstreamWriter.SendNext(1);
                Thread.Sleep(1000);

                upstreamWriter.SendComplete();
                downstreamWriter.SendComplete();

                upFinished.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();
                downFinished.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();
            }, Materializer);
        }
示例#3
0
        public void IdleTimeoutBidi_must_be_able_to_signal_timeout_once_no_traffic_on_either_sides()
        {
            this.AssertAllStagesStopped(() =>
            {
                var upWrite = this.CreatePublisherProbe <string>();
                var upRead  = this.CreateSubscriberProbe <int>();

                var downWrite = this.CreatePublisherProbe <int>();
                var downRead  = this.CreateSubscriberProbe <string>();

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var timeoutStage = b.Add(BidiFlow.BidirectionalIdleTimeout <string, int>(TimeSpan.FromSeconds(2)));

                    b.From(Source.FromPublisher(upWrite)).To(timeoutStage.Inlet1);
                    b.From(timeoutStage.Outlet1).To(Sink.FromSubscriber(downRead));
                    b.From(timeoutStage.Outlet2).To(Sink.FromSubscriber(upRead));
                    b.From(Source.FromPublisher(downWrite)).To(timeoutStage.Inlet2);

                    return(ClosedShape.Instance);
                })).Run(Materializer);

                // Request enough for the whole test
                upRead.Request(100);
                downRead.Request(100);

                upWrite.SendNext("DATA1");
                downRead.ExpectNext("DATA1");
                Thread.Sleep(1500);

                downWrite.SendNext(1);
                upRead.ExpectNext(1);
                Thread.Sleep(1500);

                upWrite.SendNext("DATA2");
                downRead.ExpectNext("DATA2");
                Thread.Sleep(1000);

                downWrite.SendNext(2);
                upRead.ExpectNext(2);

                upRead.ExpectNoMsg(TimeSpan.FromMilliseconds(500));
                var error1 = upRead.ExpectError();
                var error2 = downRead.ExpectError();

                error1.Should().BeOfType <TimeoutException>();
                error1.Message.Should().Be($"No elements passed in the last {TimeSpan.FromSeconds(2)}.");
                error2.ShouldBeEquivalentTo(error1);

                upWrite.ExpectCancellation();
                downWrite.ExpectCancellation();
            }, Materializer);
        }
示例#4
0
        public void IdleTimeoutBidi_must_not_signal_error_in_simple_loopback_case_and_pass_through_elements_unmodified()
        {
            this.AssertAllStagesStopped(() =>
            {
                var timeoutIdentity = BidiFlow.BidirectionalIdleTimeout <int, int>(TimeSpan.FromSeconds(2)).Join(Flow.Create <int>());

                var t = Source.From(Enumerable.Range(1, 100))
                        .Via(timeoutIdentity).Grouped(200)
                        .RunWith(Sink.First <IEnumerable <int> >(), Materializer);

                t.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();
                t.Result.ShouldAllBeEquivalentTo(Enumerable.Range(1, 100));
            }, Materializer);
        }
示例#5
0
        public static BidiFlow <ByteString, ByteString, ByteString, ByteString, NotUsed> Create(TimeSpan idleTimeout, EndPoint remoteAddress = null)
        {
            var connectionString = remoteAddress == null ? "" : $" on connection to [{remoteAddress}]";

            var idleException = new TcpIdleTimeoutException(
                $"TCP idle-timeout encountered{connectionString}, no bytes passed in the last {idleTimeout}",
                idleTimeout);

            var toNetTimeout = BidiFlow.FromFlows(
                Flow.Create <ByteString>().SelectError(e => e is TimeoutException ? idleException : e),
                Flow.Create <ByteString>());

            var fromNetTimeout = toNetTimeout.Reversed(); // now the bottom flow transforms the exception, the top one doesn't (since that one is "fromNet")

            return(fromNetTimeout.Atop(BidiFlow.BidirectionalIdleTimeout <ByteString, ByteString>(idleTimeout))
                   .Atop(toNetTimeout));
        }
示例#6
0
            private StreamTcp.IncomingConnection ConnectionFor(Tcp.Connected connected, IActorRef connection)
            {
                _connectionFlowsAwaitingInitialization.IncrementAndGet();

                var tcpFlow =
                    Flow.FromGraph(new IncomingConnectionStage(connection, connected.RemoteAddress, _stage._halfClose))
                    .Via(new Detacher <ByteString>()) // must read ahead for proper completions
                    .MapMaterializedValue(unit =>
                {
                    _connectionFlowsAwaitingInitialization.DecrementAndGet();
                    return(unit);
                });

                // FIXME: Previous code was wrong, must add new tests
                var handler = tcpFlow;

                if (_stage._idleTimeout.HasValue)
                {
                    handler = tcpFlow.Join(BidiFlow.BidirectionalIdleTimeout <ByteString, ByteString>(_stage._idleTimeout.Value));
                }

                return(new StreamTcp.IncomingConnection(connected.LocalAddress, connected.RemoteAddress, handler));
            }