public void A_StatefulSelectMany_must_be_able_to_restart()
        {
            var probe = Source.From(new[] { 2, 1, 3, 4, 1 }).StatefulSelectMany <int, int, NotUsed>(() =>
            {
                int?prev = null;

                return(x =>
                {
                    if (x % 3 == 0)
                    {
                        throw Ex;
                    }

                    if (prev.HasValue)
                    {
                        var result = Enumerable.Range(1, prev.Value).Select(__ => x);
                        prev = x;
                        return result;
                    }

                    prev = x;
                    return new List <int>();
                });
            })
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider))
                        .RunWith(this.SinkProbe <int>(), Materializer);

            probe.Request(2).ExpectNext(1, 1);
            probe.Request(4).ExpectNext(1, 1, 1, 1);
            probe.ExpectComplete();
        }
예제 #2
0
        public async Task A_QueueSink_should_skip_failing_messages_if_supervision_strategy_is_restart()
        {
            await Queue.DeleteIfExistsAsync();

            var queueSink = QueueSink.Create(Queue)
                            .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider));

            var t = this.SourceProbe <string>()
                    //.Select(x => new QueueMessage(x))
                    .ToMaterialized(queueSink, Keep.Both)
                    .Run(Materializer);

            var probe = t.Item1;
            var task  = t.Item2;

            probe.SendNext("1");
            await Task.Delay(500);

            await Queue.CreateAsync();

            probe.SendNext("2");
            probe.SendComplete();
            await task;

            (await Queue.ReceiveMessagesAsync()).Value[0].MessageText.Should().Be("2");
        }
예제 #3
0
        public void Conflate_must_restart_when_aggregate_throws_and_a_RestartingDecider_is_used()
        {
            var sourceProbe = this.CreatePublisherProbe <string>();
            var sinkProbe   = this.CreateSubscriberProbe <string>();
            var latch       = new TestLatch();

            var conflate = Flow.Create <string>().ConflateWithSeed(i => i, (state, elem) =>
            {
                if (elem == "two")
                {
                    latch.Open();
                    throw new TestException("two is a three letter word");
                }

                return(state + elem);
            }).WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider));

            Source.FromPublisher(sourceProbe)
            .Via(conflate)
            .To(Sink.FromSubscriber(sinkProbe))
            .WithAttributes(Attributes.CreateInputBuffer(4, 4))
            .Run(Materializer);

            var sub = sourceProbe.ExpectSubscription();

            sub.ExpectRequest(4);
            sub.SendNext("one");
            sub.SendNext("two");
            sub.SendNext("three");
            sub.SendComplete();

            //"one" should be lost
            latch.Ready(TimeSpan.FromSeconds(3));
            sinkProbe.RequestNext("three");
        }
예제 #4
0
        public async Task PlainSource_should_stop_on_errors()
        {
            int elementsCount = 10;
            var topic1        = CreateTopic(1);
            var group1        = CreateGroup(1);

            await ProduceStrings(new TopicPartition(topic1, 0), Enumerable.Range(1, elementsCount), ProducerSettings);

            var settings = CreateConsumerSettings <int>(group1).WithValueDeserializer(Deserializers.Int32);

            var probe = KafkaConsumer
                        .PlainSource(settings, Subscriptions.Assignment(new TopicPartition(topic1, 0)))
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.StoppingDecider))
                        .Select(c => c.Value)
                        .RunWith(this.SinkProbe <int>(), Materializer);

            var error = probe.Request(elementsCount).ExpectEvent(TimeSpan.FromSeconds(5));

            error.Should().BeOfType <TestSubscriber.OnError>();
            var exception = ((TestSubscriber.OnError)error).Cause;

            exception.Should().BeOfType <ConsumeException>();
            ((ConsumeException)exception).Error.IsSerializationError().Should().BeTrue();

            probe.ExpectNoMsg(TimeSpan.FromSeconds(5));
            probe.Cancel();
        }
예제 #5
0
 public void A_Flow_with_SelectAsync_must_resume_after_task_failure()
 {
     this.AssertAllStagesStopped(() =>
     {
         this.AssertAllStagesStopped(() =>
         {
             var c = this.CreateManualSubscriberProbe <int>();
             Source.From(Enumerable.Range(1, 5))
             .SelectAsync(4, n => Task.Run(() =>
             {
                 if (n == 3)
                 {
                     throw new TestException("err3");
                 }
                 return(n);
             }))
             .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
             .RunWith(Sink.FromSubscriber(c), Materializer);
             var sub = c.ExpectSubscription();
             sub.Request(10);
             new[] { 1, 2, 4, 5 }.ForEach(i => c.ExpectNext(i));
             c.ExpectComplete();
         }, Materializer);
     }, Materializer);
 }
예제 #6
0
 public void A_LazySink_must_continue_if_supervision_is_resume()
 {
     this.AssertAllStagesStopped(() =>
     {
         var sourceProbe = this.CreateManualPublisherProbe <int>();
         var lazySink    = Sink.LazySink((int a) =>
         {
             if (a == 0)
             {
                 throw Ex;
             }
             return(Task.FromResult(this.SinkProbe <int>()));
         },
                                         Fallback <TestSubscriber.Probe <int> >());
         var taskProbe =
             Source.FromPublisher(sourceProbe)
             .ToMaterialized(lazySink, Keep.Right)
             .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
             .Run(Materializer);
         var sourceSub = sourceProbe.ExpectSubscription();
         sourceSub.ExpectRequest(1);
         sourceSub.SendNext(0);
         sourceSub.ExpectRequest(1);
         sourceSub.SendNext(1);
         var probe = taskProbe.AwaitResult(RemainingOrDefault);
         probe.Request(1);
         probe.ExpectNext(1);
         probe.Cancel();
     }, Materializer);
 }
예제 #7
0
        public async Task Overriden_default_decider_on_PlainSource_should_work()
        {
            int elementsCount = 10;
            var topic1        = CreateTopic(1);
            var group1        = CreateGroup(1);

            var sourceTask = ProduceStrings(new TopicPartition(topic1, 0), Enumerable.Range(1, elementsCount), ProducerSettings);

            await GuardWithTimeoutAsync(sourceTask, TimeSpan.FromSeconds(3));

            var settings = CreateConsumerSettings <int>(group1).WithValueDeserializer(Deserializers.Int32);
            var decider  = new OverridenConsumerDecider(settings.AutoCreateTopicsEnabled);

            var probe = KafkaConsumer
                        .PlainSource(settings, Subscriptions.Assignment(new TopicPartition(topic1, 0)))
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(decider.Decide))
                        .Select(c => c.Value)
                        .RunWith(this.SinkProbe <int>(), Materializer);

            probe.Request(elementsCount);
            probe.ExpectNoMsg(TimeSpan.FromSeconds(10));
            // this is twice elementCount because Decider is called twice on each exceptions
            decider.CallCount.Should().Be(elementsCount * 2);
            probe.Cancel();
        }
예제 #8
0
        public void A_UnfoldResourceSource_must_close_and_open_stream_again_when_strategy_is_restart()
        {
            this.AssertAllStagesStopped(() =>
            {
                var p = Source.UnfoldResource(_open, reader =>
                {
                    var s = reader.ReadLine();
                    if (s != null && s.Contains("b"))
                    {
                        throw new TestException("");
                    }
                    return(s ?? Option <string> .None);
                }, Close)
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider))
                        .RunWith(Sink.AsPublisher <string>(false), Materializer);
                var c = this.CreateManualSubscriberProbe <string>();

                p.Subscribe(c);
                var sub = c.ExpectSubscription();

                Enumerable.Range(0, 20).ForEach(i =>
                {
                    sub.Request(1);
                    c.ExpectNext().Should().Be(ManyLinesArray[0]);
                });
                sub.Cancel();
            }, Materializer);
        }
        public void A_ForeachParallel_must_finish_after_function_thrown_exception()
        {
            this.AssertAllStagesStopped(() =>
            {
                var probe = CreateTestProbe();
                var latch = new TestLatch(1);

                var p = Source.From(Enumerable.Range(1, 5)).RunWith(Sink.ForEachParallel <int>(3, n =>
                {
                    if (n == 3)
                    {
                        throw new TestException("err2");
                    }

                    probe.Ref.Tell(n);
                    latch.Ready(TimeSpan.FromSeconds(10));
                }).WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.StoppingDecider)), Materializer);

                // make sure the stream is up and running, otherwise the latch is maybe ready before the third message arrives
                Thread.Sleep(500);
                latch.CountDown();
                probe.ExpectMsgAllOf(1, 2);

                var ex = p.Invoking(t => t.Wait(TimeSpan.FromSeconds(1))).Should().Throw <AggregateException>().Which;
                ex.Flatten().InnerException.Should().BeOfType <TestException>();
                ex.Flatten().InnerException.Message.Should().Be("err2");

                p.IsCompleted.Should().BeTrue();
            }, Materializer);
        }
예제 #10
0
        public async Task PlainSource_with_directive_override_should_resume_on_deserialization_errors()
        {
            var callCount = 0;

            Directive Decider(Exception cause)
            {
                if (cause is ConsumeException ex && ex.Error.IsSerializationError())
                {
                    callCount++;
                    return(Directive.Resume);
                }
                return(Directive.Stop);
            }

            int elementsCount = 10;
            var topic1        = CreateTopic(1);
            var group1        = CreateGroup(1);

            await ProduceStrings(new TopicPartition(topic1, 0), Enumerable.Range(1, elementsCount), ProducerSettings);

            var settings = CreateConsumerSettings <int>(group1).WithValueDeserializer(Deserializers.Int32);

            var probe = KafkaConsumer
                        .PlainSource(settings, Subscriptions.Assignment(new TopicPartition(topic1, 0)))
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Decider))
                        .Select(c => c.Value)
                        .RunWith(this.SinkProbe <int>(), Materializer);

            probe.Request(elementsCount);
            probe.ExpectNoMsg(TimeSpan.FromSeconds(10));
            // this is twice elementCount because Decider is called twice on each exceptions
            callCount.Should().Be(elementsCount * 2);
            probe.Cancel();
        }
예제 #11
0
 /// <summary>
 /// KafkaSourceStage
 /// </summary>
 /// <param name="stageName">Stage name</param>
 /// <param name="autoCreateTopics">Kafka source should auto create topics</param>
 protected KafkaSourceStage(string stageName)
 {
     StageName         = stageName;
     Shape             = new SourceShape <TMessage>(Out);
     InitialAttributes = Attributes.CreateName(StageName)
                         .And(ActorAttributes.CreateSupervisionStrategy(new DefaultConsumerDecider(true).Decide));
 }
예제 #12
0
        public void A_AggregateAsync_must_restart_after_task_failure()
        {
            this.AssertAllStagesStopped(() =>
            {
                var probe = this.CreateSubscriberProbe <Tuple <int, int> >();
                Source.From(Enumerable.Range(1, 5)).AggregateAsync(Tuple.Create(0, 1), (t, n) =>
                {
                    var i   = t.Item1;
                    var res = t.Item2;
                    return(Task.Run(() =>
                    {
                        if (n == 3)
                        {
                            throw new Exception("err3");
                        }

                        return Tuple.Create(n, i + res * n);
                    }));
                })
                .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider))
                .To(Sink.FromSubscriber(probe))
                .Run(Materializer);

                var subscription = probe.ExpectSubscription();
                subscription.Request(10);
                probe.ExpectNext(Tuple.Create(5, 24));
                probe.ExpectComplete();
            }, Materializer);
        }
예제 #13
0
        public async Task PlainPartitionedSource_should_be_signalled_about_serialization_errors()
        {
            var topic = CreateTopic(1);
            var group = CreateGroup(1);

            await ProduceStrings(topic, new int[] { 0 }, ProducerSettings); // Produce "0" string

            var settings = CreateConsumerSettings <int>(group).WithValueDeserializer(Deserializers.Int32);

            var(control1, partitionedProbe) = KafkaConsumer.PlainPartitionedSource(settings, Subscriptions.Topics(topic))
                                              .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.StoppingDecider))
                                              .ToMaterialized(this.SinkProbe <(TopicPartition, Source <ConsumeResult <Null, int>, NotUsed>)>(), Keep.Both)
                                              .Run(Materializer);

            partitionedProbe.Request(3);

            var subsources = partitionedProbe.Within(TimeSpan.FromSeconds(10), () => partitionedProbe.ExpectNextN(3).Select(t => t.Item2).ToList());
            var substream  = subsources.Aggregate((s1, s2) => s1.Merge(s2)).RunWith(this.SinkProbe <ConsumeResult <Null, int> >(), Materializer);

            substream.Request(1);

            await ProduceStrings(topic, new int[] { 0 }, ProducerSettings); // Produce "0" string

            Within(TimeSpan.FromSeconds(10), () => substream.ExpectError().Should().BeOfType <SerializationException>());

            var shutdown = control1.Shutdown();

            AwaitCondition(() => shutdown.IsCompleted, TimeSpan.FromSeconds(10));
        }
예제 #14
0
        public void Flow_with_ask_a_failure_mid_stream_must_skip_element_with_resume_strategy() => this.AssertAllStagesStopped(() =>
        {
            var p        = CreateTestProbe();
            var input    = new[] { "a", "b", "c", "d", "e", "f" };
            var elements = Source.From(input)
                           .Ask <string>(p.Ref, _timeout, 5)
                           .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Supervision.Deciders.ResumingDecider))
                           .RunWith(Sink.Seq <string>(), _materializer);

            // the problematic ordering:
            p.ExpectMsg("a");
            p.LastSender.Tell("a");

            p.ExpectMsg("b");
            p.LastSender.Tell("b");

            p.ExpectMsg("c");
            var cSender = p.LastSender;

            p.ExpectMsg("d");
            p.LastSender.Tell("d");

            p.ExpectMsg("e");
            p.LastSender.Tell("e");

            p.ExpectMsg("f");
            p.LastSender.Tell("f");

            cSender.Tell(new Status.Failure(new Exception("Boom!")));
            elements.Result.Should().BeEquivalentTo(new[] { "a", "b", /*no c*/ "d", "e", "f" });
        }, _materializer);
        public void A_UnfoldResourceAsyncSource_must_continue_when_strategy_is_resume_and_exception_happened()
        {
            this.AssertAllStagesStopped(() =>
            {
                var p = Source.UnfoldResourceAsync(_open, reader =>
                {
                    var s = reader.ReadLine();
                    if (s != null && s.Contains("b"))
                    {
                        throw new TestException("");
                    }
                    return(Task.FromResult(s ?? Option <string> .None));
                }, Close)
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
                        .RunWith(Sink.AsPublisher <string>(false), Materializer);
                var c = this.CreateManualSubscriberProbe <string>();

                p.Subscribe(c);
                var sub = c.ExpectSubscription();

                Enumerable.Range(0, 50).ForEach(i =>
                {
                    sub.Request(1);
                    c.ExpectNext().Should().Be(i < 10 ? ManyLinesArray[i] : ManyLinesArray[i + 10]);
                });
                sub.Request(1);
                c.ExpectComplete();
            }, Materializer);
        }
예제 #16
0
        public async Task PlainSource_should_resume_on_deserialization_errors()
        {
            Directive Decider(Exception cause) => cause is SerializationException
                ? Directive.Resume
                : Directive.Stop;

            int elementsCount = 10;
            var topic1        = CreateTopic(1);
            var group1        = CreateGroup(1);

            await Produce(topic1, Enumerable.Range(1, elementsCount), ProducerSettings);

            var settings = ConsumerSettings <Null, int> .Create(Sys, null, new IntDeserializer())
                           .WithBootstrapServers(KafkaUrl)
                           .WithProperty("auto.offset.reset", "earliest")
                           .WithGroupId(group1);

            var probe = KafkaConsumer
                        .PlainSource(settings, Subscriptions.Assignment(new TopicPartition(topic1, 0)))
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Decider))
                        .Select(c => c.Value)
                        .RunWith(this.SinkProbe <int>(), _materializer);

            probe.Request(elementsCount);
            probe.ExpectNoMsg(TimeSpan.FromSeconds(10));
            probe.Cancel();
        }
예제 #17
0
        public void Stream_supervision_must_support_restart()
        {
            var withAttributes =
                FailingMap.WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider));
            var result = Run(withAttributes);

            result.ShouldAllBeEquivalentTo(new[] { 1, 2, 4, 5, 1, 2, 4, 5 });
        }
        public async Task PlainSink_should_resume_on_deserialization_errors()
        {
            var callCount = 0;

            Directive Decider(Exception cause)
            {
                callCount++;
                switch (cause)
                {
                case ProduceException <Null, string> ex when ex.Error.IsSerializationError():
                    return(Directive.Resume);

                default:
                    return(Directive.Stop);
                }
            }

            var elementsCount = 10;
            var topic1        = CreateTopic(1);
            var group1        = CreateGroup(1);

            var producerSettings = ProducerSettings <Null, string>
                                   .Create(Sys, null, new FailingSerializer())
                                   .WithBootstrapServers(Fixture.KafkaServer);

            var sink = KafkaProducer.PlainSink(producerSettings)
                       .AddAttributes(ActorAttributes.CreateSupervisionStrategy(Decider));

            var sourceTask = Source
                             .From(new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })
                             .Select(elem => new ProducerRecord <Null, string>(new TopicPartition(topic1, 0), elem.ToString()))
                             .RunWith(sink, Materializer);

            var timeoutTask  = Task.Delay(TimeSpan.FromSeconds(5));
            var completeTask = await Task.WhenAny(sourceTask, timeoutTask);

            if (completeTask == timeoutTask)
            {
                throw new Exception("Producer timed out");
            }

            var settings = CreateConsumerSettings <Null, string>(group1).WithValueDeserializer(new StringDeserializer());
            var probe    = KafkaConsumer
                           .PlainSource(settings, Subscriptions.Assignment(new TopicPartition(topic1, 0)))
                           .Select(c => c.Value)
                           .RunWith(this.SinkProbe <string>(), Materializer);

            probe.Request(elementsCount);
            for (var i = 0; i < 9; i++)
            {
                Log.Info($">>>>>>>>>>> {i}");
                probe.ExpectNext();
            }
            callCount.Should().Be(1);
            probe.Cancel();
        }
예제 #19
0
        public void Conflate_must_restart_when_aggregate_throws_and_a_ResumingDecider_is_used()
        {
            var sourceProbe = this.CreatePublisherProbe <int>();
            var sinkProbe   = this.CreateManualSubscriberProbe <List <int> >();
            var saw4Latch   = new TestLatch();

            var graph = Source.FromPublisher(sourceProbe).ConflateWithSeed(i => new List <int> {
                i
            },
                                                                           (state, elem) =>
            {
                if (elem == 2)
                {
                    throw new TestException("three is a four letter word");
                }

                if (elem == 4)
                {
                    saw4Latch.Open();
                }

                state.Add(elem);
                return(state);
            })
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
                        .To(Sink.FromSubscriber(sinkProbe))
                        .WithAttributes(Attributes.CreateInputBuffer(1, 1));

            RunnableGraph.FromGraph(graph).Run(Materializer);

            var sub     = sourceProbe.ExpectSubscription();
            var sinkSub = sinkProbe.ExpectSubscription();

            // push the first three values, the third will trigger
            // the exception
            sub.ExpectRequest(1);
            sub.SendNext(1);

            // causing the 1 to get thrown away
            sub.ExpectRequest(1);
            sub.SendNext(2);

            sub.ExpectRequest(1);
            sub.SendNext(3);

            sub.ExpectRequest(1);
            sub.SendNext(4);

            // and consume it, so that the next element
            // will trigger seed
            saw4Latch.Ready(TimeSpan.FromSeconds(3));
            sinkSub.Request(1);

            sinkProbe.ExpectNext().ShouldAllBeEquivalentTo(new [] { 1, 3, 4 });
        }
예제 #20
0
        public void Flow_with_ask_must_resume_after_multiple_failures() => this.AssertAllStagesStopped(() =>
        {
            var aref = ReplierFailAllExceptOn(6);
            var t    = Source.From(Enumerable.Range(1, 6))
                       .Ask <Reply>(aref, _timeout, 2)
                       .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Supervision.Deciders.ResumingDecider))
                       .RunWith(Sink.First <Reply>(), _materializer);

            t.Wait(3.Seconds()).Should().BeTrue();
            t.Result.Should().Be(new Reply(6));
        }, _materializer);
예제 #21
0
        public void A_Log_on_Source_must_follow_supervision_strategy_when_Exception_thrown()
        {
            var ex     = new TestException("test");
            var future = Source.From(Enumerable.Range(1, 5))
                         .Log("hi", n => { throw ex; })
                         .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
                         .RunWith(Sink.Aggregate <int, int>(0, (i, i1) => i + i1), Materializer);

            future.Wait(TimeSpan.FromMilliseconds(500)).Should().BeTrue();
            future.Result.Should().Be(0);
        }
예제 #22
0
        private TestSubscriber.ManualProbe <string> WhenNullElement(ICollection <string> elements, string zero, Decider decider = null)
        {
            decider = decider ?? Deciders.StoppingDecider;

            return(Source.From(elements)
                   .ScanAsync(zero, (i, i1) => Task.FromResult(i1 != "null" ? i1 : null))
                   .WithAttributes(ActorAttributes.CreateSupervisionStrategy(decider))
                   .RunWith(this.SinkProbe <string>(), Materializer)
                   .Request(elements.Count + 1)
                   .ExpectNext(zero));
        }
예제 #23
0
        public void GroupBy_must_resume_stream_when_GroupBy_function_throws()
        {
            this.AssertAllStagesStopped(() =>
            {
                var publisherProbe = TestPublisher.CreateManualProbe <int>(this);
                var ex             = new TestException("test");
                var publisher      = Source.FromPublisher(publisherProbe).GroupBy(2, i =>
                {
                    if (i == 2)
                    {
                        throw ex;
                    }
                    return(i % 2);
                })
                                     .Lift(x => x % 2)
                                     .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
                                     .RunWith(Sink.AsPublisher <Tuple <int, Source <int, NotUsed> > >(false), Materializer);

                var subscriber = TestSubscriber.CreateManualProbe <Tuple <int, Source <int, NotUsed> > >(this);
                publisher.Subscribe(subscriber);

                var upstreamSubscription   = publisherProbe.ExpectSubscription();
                var downstreamSubscription = subscriber.ExpectSubscription();
                downstreamSubscription.Request(100);

                upstreamSubscription.SendNext(1);

                var substream        = subscriber.ExpectNext().Item2;
                var substreamPuppet1 = new StreamPuppet(substream.RunWith(Sink.AsPublisher <int>(false), Materializer), this);

                substreamPuppet1.Request(10);
                substreamPuppet1.ExpectNext(1);

                upstreamSubscription.SendNext(2);
                upstreamSubscription.SendNext(4);

                var substream2       = subscriber.ExpectNext().Item2;
                var substreamPuppet2 = new StreamPuppet(substream2.RunWith(Sink.AsPublisher <int>(false), Materializer), this);
                substreamPuppet2.Request(10);
                substreamPuppet2.ExpectNext(4);

                upstreamSubscription.SendNext(3);
                substreamPuppet1.ExpectNext(3);

                upstreamSubscription.SendNext(6);
                substreamPuppet2.ExpectNext(6);

                upstreamSubscription.SendComplete();
                subscriber.ExpectComplete();
                substreamPuppet1.ExpectComplete();
                substreamPuppet2.ExpectComplete();
            }, Materializer);
        }
예제 #24
0
        public async Task SupervisionStrategy_Decider_on_PlainSink_should_work()
        {
            var callCount = 0;

            Directive Decider(Exception cause)
            {
                callCount++;
                switch (cause)
                {
                case ProduceException <Null, string> ex when ex.Error.IsSerializationError():
                    return(Directive.Resume);

                default:
                    return(Directive.Stop);
                }
            }

            var topic1 = CreateTopic(1);
            var group1 = CreateGroup(1);

            var producerSettings = ProducerSettings <Null, string>
                                   .Create(Sys, null, new FailingSerializer())
                                   .WithBootstrapServers(Fixture.KafkaServer);

            // Exception is injected into the sink by the FailingSerializer serializer, it throws an exceptions
            // when the message "5" is encountered.
            var sourceTask = Source
                             .From(new [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 })
                             .Select(elem => new ProducerRecord <Null, string>(new TopicPartition(topic1, 0), elem.ToString()))
                             .RunWith(
                KafkaProducer.PlainSink(producerSettings)
                .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Decider)),
                Materializer);

            await GuardWithTimeoutAsync(sourceTask, TimeSpan.FromSeconds(5));

            var settings = CreateConsumerSettings <Null, string>(group1).WithValueDeserializer(new StringDeserializer());
            var probe    = KafkaConsumer
                           .PlainSource(settings, Subscriptions.Assignment(new TopicPartition(topic1, 0)))
                           .Select(c => c.Value)
                           .RunWith(this.SinkProbe <string>(), Materializer);

            probe.Request(10);
            for (var i = 0; i < 9; i++)
            {
                var message = probe.ExpectNext();
                Log.Info($"> [{i}]: {message}");
            }
            callCount.Should().Be(1);
            probe.Cancel();
        }
예제 #25
0
        public void A_Flow_with_SelectAsyncUnordered_must_resume_when_task_is_completed_with_null()
        {
            var c = TestSubscriber.CreateManualProbe <string>(this);

            Source.From(new[] { "a", "b", "c" })
            .SelectAsyncUnordered(4, s => s.Equals("b") ? Task.FromResult(null as string) : Task.FromResult(s))
            .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
            .To(Sink.FromSubscriber(c)).Run(Materializer);
            var sub = c.ExpectSubscription();

            sub.Request(10);
            c.ExpectNextUnordered("a", "c");
            c.ExpectComplete();
        }
예제 #26
0
        public async Task SupervisionStrategy_Decider_on_Consumer_Downstream_should_work()
        {
            var topic          = CreateTopic(1);
            var group          = CreateGroup(1);
            var topicPartition = new TopicPartition(topic, 0);
            var callCount      = 0;

            Directive Decider(Exception cause)
            {
                callCount++;
                if (cause.Message == "BOOM!")
                {
                    return(Directive.Restart);
                }
                return(Directive.Stop);
            }

            var consumerSettings = CreateConsumerSettings <string>(group);
            var counter          = 0;

            await Source.From(Enumerable.Range(1, 11))
            .Select(elem => new ProducerRecord <Null, string>(topicPartition, elem.ToString()))
            .RunWith(KafkaProducer.PlainSink(ProducerSettings), Materializer);

            var(_, probe) = KafkaConsumer
                            .PlainSource(consumerSettings, Subscriptions.Assignment(topicPartition))
                            .Select(c =>
            {
                counter++;
                // fail once on counter 5
                if (counter == 5)
                {
                    throw new Exception("BOOM!");
                }
                return(c.Message.Value);
            })
                            .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Decider))
                            .ToMaterialized(this.SinkProbe <string>(), Keep.Both)
                            .Run(Materializer);

            probe.Request(10);
            for (var i = 0; i < 9; i++)
            {
                var message = probe.ExpectNext(TimeSpan.FromSeconds(10));
                Log.Info(message);
            }
            probe.Cancel();

            callCount.Should().Be(1);
        }
예제 #27
0
        public void A_QueueSink_should_retry_failing_messages_if_supervision_strategy_is_resume()
        {
            Queue.DeleteIfExists();
            var messages  = new[] { "1", "2" };
            var queueSink = QueueSink.Create(Queue)
                            .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider));

            var t = Source.From(messages)
                    .Select(x => new CloudQueueMessage(x))
                    .RunWith(queueSink, Materializer);

            Thread.Sleep(1000);
            Queue.Create();
            t.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();
            Queue.GetMessages(2).Select(x => x.AsString).ShouldAllBeEquivalentTo(messages);
        }
예제 #28
0
        public void Conflate_must_restart_when_seed_throws_and_a_RestartDescider_is_used()
        {
            var sourceProbe   = this.CreatePublisherProbe <int>();
            var sinkProbe     = this.CreateManualSubscriberProbe <int>();
            var exceptionlath = new TestLatch();

            var graph = Source.FromPublisher(sourceProbe).ConflateWithSeed(i =>
            {
                if (i % 2 == 0)
                {
                    exceptionlath.Open();
                    throw new TestException("I hate even seed numbers");
                }
                return(i);
            }, (sum, i) => sum + i)
                        .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider))
                        .To(Sink.FromSubscriber(sinkProbe))
                        .WithAttributes(Attributes.CreateInputBuffer(1, 1));

            RunnableGraph.FromGraph(graph).Run(Materializer);

            var sub     = sourceProbe.ExpectSubscription();
            var sinkSub = sinkProbe.ExpectSubscription();

            // push the first value
            sub.ExpectRequest(1);
            sub.SendNext(1);

            // and consume it, so that the next element
            // will trigger seed
            sinkSub.Request(1);
            sinkProbe.ExpectNext(1);

            sub.ExpectRequest(1);
            sub.SendNext(2);

            // make sure the seed exception happened
            // before going any further
            exceptionlath.Ready(TimeSpan.FromSeconds(3));

            sub.ExpectRequest(1);
            sub.SendNext(3);

            // now we should have lost the 2 and the accumulated state
            sinkSub.Request(1);
            sinkProbe.ExpectNext(3);
        }
예제 #29
0
 public void A_Flow_with_SelectAsyncUnordered_must_resume_when_SelectAsyncUnordered_throws()
 {
     Source.From(Enumerable.Range(1, 5))
     .SelectAsyncUnordered(4, n =>
     {
         if (n == 3)
         {
             throw new TestException("err4");
         }
         return(Task.FromResult(n));
     })
     .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.ResumingDecider))
     .RunWith(this.SinkProbe <int>(), Materializer)
     .Request(10)
     .ExpectNextUnordered(1, 2, 4, 5)
     .ExpectComplete();
 }
예제 #30
0
        public void A_Collect_must_restart_when_Collect_throws()
        {
            bool ThrowOnTwo(int x) => x == 2 ? throw new TestException("") : true;

            var probe =
                Source.From(Enumerable.Range(1, 3))
                .Collect(ThrowOnTwo, x => x)
                .WithAttributes(ActorAttributes.CreateSupervisionStrategy(Deciders.RestartingDecider))
                .RunWith(this.SinkProbe <int>(), Materializer);

            probe.Request(1);
            probe.ExpectNext(1);
            probe.Request(1);
            probe.ExpectNext(3);
            probe.Request(1);
            probe.ExpectComplete();
        }