Ejemplo n.º 1
0
        //
        // Flow
        //

        /// <summary>
        /// Helps reuse all the SetupFlow code for both methods: WithBackoff, and OnlyOnFailuresWithBackoff
        /// </summary>
        private static Flow <TIn, TOut, NotUsed> RestartFlowFactory <TIn, TOut, TMat>(Func <Flow <TIn, TOut, TMat> > flowFactory, TimeSpan minBackoff, TimeSpan maxBackoff, double randomFactor, int maxRestarts, bool onlyOnFailures)
        {
            // choose the correct backoff method
            return(onlyOnFailures
                ? RestartFlow.OnFailuresWithBackoff(flowFactory, minBackoff, maxBackoff, randomFactor, maxRestarts)
                : RestartFlow.WithBackoff(flowFactory, minBackoff, maxBackoff, randomFactor, maxRestarts));
        }
Ejemplo n.º 2
0
        //
        // Flow
        //

        /// <summary>
        /// Helps reuse all the SetupFlow code for both methods: WithBackoff, and OnlyOnFailuresWithBackoff
        /// </summary>
        private static Flow <TIn, TOut, NotUsed> RestartFlowFactory <TIn, TOut, TMat>(Func <Flow <TIn, TOut, TMat> > flowFactory, bool onlyOnFailures, RestartSettings settings)
        {
            // choose the correct backoff method
            return(onlyOnFailures
                ? RestartFlow.OnFailuresWithBackoff(flowFactory, settings)
                : RestartFlow.WithBackoff(flowFactory, settings));
        }
Ejemplo n.º 3
0
        //
        // Flow
        //

        private Tuple <AtomicCounter, TestPublisher.Probe <string>, TestSubscriber.Probe <string>, TestPublisher.Probe <string>, TestSubscriber.Probe <string> > SetupFlow(TimeSpan minBackoff, TimeSpan maxBackoff)
        {
            var created       = new AtomicCounter(0);
            var probe1        = this.SourceProbe <string>().ToMaterialized(this.SinkProbe <string>(), Keep.Both).Run(Materializer);
            var flowInSource  = probe1.Item1;
            var flowInProbe   = probe1.Item2;
            var probe2        = this.SourceProbe <string>().ToMaterialized(BroadcastHub.Sink <string>(), Keep.Both).Run(Materializer);
            var flowOutProbe  = probe2.Item1;
            var flowOutSource = probe2.Item2;

            // We can't just use ordinary probes here because we're expecting them to get started/restarted. Instead, we
            // simply use the probes as a message bus for feeding and capturing events.
            var probe3 = this.SourceProbe <string>().ViaMaterialized(RestartFlow.WithBackoff(() =>
            {
                created.IncrementAndGet();
                var snk = Flow.Create <string>()
                          .TakeWhile(s => s != "cancel")
                          .To(Sink.ForEach <string>(c => flowInSource.SendNext(c))
                              .MapMaterializedValue(task => task.ContinueWith(
                                                        t1 =>
                {
                    if (t1.IsFaulted || t1.IsCanceled)
                    {
                        flowInSource.SendNext("in error");
                    }
                    else
                    {
                        flowInSource.SendNext("in complete");
                    }
                })));

                var src = flowOutSource.TakeWhile(s => s != "complete").Select(c =>
                {
                    if (c == "error")
                    {
                        throw new ArgumentException("failed");
                    }
                    return(c);
                }).WatchTermination((s1, task) =>
                {
                    task.ContinueWith(_ =>
                    {
                        flowInSource.SendNext("out complete");
                        return(NotUsed.Instance);
                    }, TaskContinuationOptions.OnlyOnRanToCompletion);
                    return(s1);
                });

                return(Flow.FromSinkAndSource(snk, src));
            }, minBackoff, maxBackoff, 0), Keep.Left)
                         .ToMaterialized(this.SinkProbe <string>(), Keep.Both).Run(Materializer);
            var source = probe3.Item1;
            var sink   = probe3.Item2;

            return(Tuple.Create(created, source, flowInProbe, flowOutProbe, sink));
        }
Ejemplo n.º 4
0
        public void A_restart_with_backoff_flow_should_run_normally()
        {
            this.AssertAllStagesStopped(() =>
            {
                var created       = new AtomicCounter(0);
                var(source, sink) = this.SourceProbe <string>().ViaMaterialized(RestartFlow.WithBackoff(() =>
                {
                    created.IncrementAndGet();
                    return(Flow.Create <string>());
                }, _shortRestartSettings), Keep.Left).ToMaterialized(this.SinkProbe <string>(), Keep.Both).Run(Materializer);

                source.SendNext("a");
                sink.RequestNext("a");
                source.SendNext("b");
                sink.RequestNext("b");

                created.Current.Should().Be(1);
                source.SendComplete();
            }, Materializer);
        }
Ejemplo n.º 5
0
        public void A_restart_with_backoff_flow_should_run_normally()
        {
            this.AssertAllStagesStopped(() =>
            {
                var created = new AtomicCounter(0);
                var tuple   = this.SourceProbe <string>().ViaMaterialized(RestartFlow.WithBackoff(() =>
                {
                    created.IncrementAndGet();
                    return(Flow.Create <string>());;
                }, TimeSpan.FromMilliseconds(10), TimeSpan.FromMilliseconds(20), 0), Keep.Left).ToMaterialized(this.SinkProbe <string>(), Keep.Both).Run(Materializer);
                var source = tuple.Item1;
                var sink   = tuple.Item2;

                source.SendNext("a");
                sink.RequestNext("a");
                source.SendNext("b");
                sink.RequestNext("b");

                created.Current.Should().Be(1);
                source.SendComplete();
            }, Materializer);
        }