예제 #1
0
        public void UnzipWith_must_work_with_up_to_6_outputs()
        {
            // the jvm version uses 20 outputs but we have only 7 so changed this spec a little bit

            this.AssertAllStagesStopped(() =>
            {
                var probe0 = TestSubscriber.CreateManualProbe <int>(this);
                var probe1 = TestSubscriber.CreateManualProbe <string>(this);
                var probe2 = TestSubscriber.CreateManualProbe <int>(this);
                var probe3 = TestSubscriber.CreateManualProbe <string>(this);
                var probe4 = TestSubscriber.CreateManualProbe <int>(this);
                var probe5 = TestSubscriber.CreateManualProbe <string>(this);

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    // odd input ports will be Int, even input ports will be String
                    var unzip =
                        b.Add(
                            new UnzipWith <List <int>, int, string, int, string, int, string>(
                                ints =>
                                Tuple.Create(ints[0], ints[0].ToString(), ints[1], ints[1].ToString(), ints[2],
                                             ints[2].ToString())));

                    var source = Source.Single(Enumerable.Range(1, 3).ToList());

                    b.From(source).To(unzip.In);
                    b.From(unzip.Out0).To(Sink.FromSubscriber(probe0));
                    b.From(unzip.Out1).To(Sink.FromSubscriber(probe1));
                    b.From(unzip.Out2).To(Sink.FromSubscriber(probe2));
                    b.From(unzip.Out3).To(Sink.FromSubscriber(probe3));
                    b.From(unzip.Out4).To(Sink.FromSubscriber(probe4));
                    b.From(unzip.Out5).To(Sink.FromSubscriber(probe5));

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

                probe0.ExpectSubscription().Request(1);
                probe1.ExpectSubscription().Request(1);
                probe2.ExpectSubscription().Request(1);
                probe3.ExpectSubscription().Request(1);
                probe4.ExpectSubscription().Request(1);
                probe5.ExpectSubscription().Request(1);

                probe0.ExpectNext(1);
                probe1.ExpectNext("1");
                probe2.ExpectNext(2);
                probe3.ExpectNext("2");
                probe4.ExpectNext(3);
                probe5.ExpectNext("3");

                probe0.ExpectComplete();
                probe1.ExpectComplete();
                probe2.ExpectComplete();
                probe3.ExpectComplete();
                probe4.ExpectComplete();
                probe5.ExpectComplete();
            }, Materializer);
        }
        public void GraphDSLs_must_support_wikipedia_Topological_sorting_2()
        {
            Func <int, Source <int, Tuple <Task <IEnumerable <int> >, Task <IEnumerable <int> >, Task <IEnumerable <int> > > > > source =
                i =>
                Source.From(new[] { i })
                .MapMaterializedValue <Tuple <Task <IEnumerable <int> >, Task <IEnumerable <int> >, Task <IEnumerable <int> > > >(
                    _ => null);

            // see https://en.wikipedia.org/wiki/Topological_sorting#mediaviewer/File:Directed_acyclic_graph.png
            var seqSink = Sink.First <IEnumerable <int> >();
            var t       = RunnableGraph.FromGraph(GraphDsl.Create(seqSink, seqSink, seqSink, Tuple.Create, (b, sink2, sink9, sink10) =>
            {
                var b3  = b.Add(new Broadcast <int>(2));
                var b7  = b.Add(new Broadcast <int>(2));
                var b11 = b.Add(new Broadcast <int>(3));
                var m8  = b.Add(new Merge <int>(2));
                var m9  = b.Add(new Merge <int>(2));
                var m10 = b.Add(new Merge <int>(2));
                var m11 = b.Add(new Merge <int>(2));

                var in3 = source(3);
                var in5 = source(5);
                var in7 = source(7);

                // First layer
                b.From(in7).To(b7.In);
                b.From(b7.Out(0)).To(m11.In(0));
                b.From(b7.Out(1)).To(m8.In(0));

                b.From(in5).To(m11.In(1));

                b.From(in3).To(b3.In);
                b.From(b3.Out(0)).To(m8.In(1));
                b.From(b3.Out(1)).To(m10.In(0));

                // Second layer
                b.From(m11.Out).To(b11.In);
                b.From(b11.Out(0)).Via(Flow.Create <int>().Grouped(1000)).To(sink2.Inlet);
                b.From(b11.Out(1)).To(m9.In(0));
                b.From(b11.Out(2)).To(m10.In(1));

                b.From(m8.Out).To(m9.In(1));

                // Third layer
                b.From(m9.Out).Via(Flow.Create <int>().Grouped(1000)).To(sink9.Inlet);
                b.From(m10.Out).Via(Flow.Create <int>().Grouped(1000)).To(sink10.Inlet);

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

            var task = Task.WhenAll(t.Item1, t.Item2, t.Item3);

            task.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();

            task.Result[0].ShouldAllBeEquivalentTo(new[] { 5, 7 });
            task.Result[1].ShouldAllBeEquivalentTo(new[] { 3, 5, 7, 7 });
            task.Result[2].ShouldAllBeEquivalentTo(new[] { 3, 5, 7 });
        }
예제 #3
0
        public void A_Graph_with_materialized_value_must_produce_NotUsed_when_not_importing_materialized_value(bool autoFusing)
        {
            var materializer = CreateMaterializer(autoFusing);
            var source       = Source.FromGraph(GraphDsl.Create(b => new SourceShape <NotUsed>(b.MaterializedValue)));
            var task         = source.RunWith(Sink.Seq <NotUsed>(), materializer);

            task.Wait(TimeSpan.FromSeconds(3));
            task.Result.ShouldAllBeEquivalentTo(NotUsed.Instance);
        }
        public DownloadCoordinator(CrawlJob job, IActorRef commander, IActorRef downloadsTracker,
                                   long maxConcurrentDownloads)
        {
            Job = job;
            DownloadsTracker       = downloadsTracker;
            MaxConcurrentDownloads = maxConcurrentDownloads;
            Commander = commander;
            Stats     = new CrawlJobStats(Job);
            var selfHtmlSink = Sink.ActorRef <CheckDocuments>(Self, StreamCompleteTick.Instance);
            var selfDocSink  = Sink.ActorRef <CompletedDocument>(Self, StreamCompleteTick.Instance);
            var selfImgSink  = Sink.ActorRef <CompletedDocument>(Self, StreamCompleteTick.Instance);
            var htmlFlow     = Flow.Create <CrawlDocument>().Via(DownloadFlow.SelectDocType())
                               .Throttle(30, TimeSpan.FromSeconds(5), 100, ThrottleMode.Shaping)
                               .Via(DownloadFlow.ProcessHtmlDownloadFor(DefaultMaxConcurrentDownloads, HttpClientFactory.GetClient()));

            var imageFlow = Flow.Create <CrawlDocument>()
                            .Via(DownloadFlow.SelectDocType())
                            .Throttle(30, TimeSpan.FromSeconds(1), 100, ThrottleMode.Shaping)
                            .Via(DownloadFlow.ProcessImageDownloadFor(DefaultMaxConcurrentDownloads, HttpClientFactory.GetClient()))
                            .Via(DownloadFlow.ProcessCompletedDownload());

            var source = Source.ActorRef <CrawlDocument>(5000, OverflowStrategy.DropTail);

            var graph = GraphDsl.Create(source, (builder, s) =>
            {
                // html flows
                var downloadHtmlFlow       = builder.Add(htmlFlow);
                var downloadBroadcast      = builder.Add(new Broadcast <DownloadHtmlResult>(2));
                var completedDownload      = builder.Add(DownloadFlow.ProcessCompletedHtmlDownload());
                var parseCompletedDownload = builder.Add(ParseFlow.GetParseFlow(Job));
                var htmlSink = builder.Add(selfHtmlSink);
                var docSink  = builder.Add(selfDocSink);
                builder.From(downloadHtmlFlow).To(downloadBroadcast);
                builder.From(downloadBroadcast.Out(0)).To(completedDownload.Inlet);
                builder.From(downloadBroadcast.Out(1)).To(parseCompletedDownload.Inlet);
                builder.From(parseCompletedDownload).To(htmlSink);
                builder.From(completedDownload).To(docSink);

                // image flows
                var imgSink           = builder.Add(selfImgSink);
                var downloadImageFlow = builder.Add(imageFlow);
                builder.From(downloadImageFlow).To(imgSink);

                var sourceBroadcast = builder.Add(new Broadcast <CrawlDocument>(2));
                builder.From(sourceBroadcast.Out(0)).To(downloadImageFlow.Inlet);
                builder.From(sourceBroadcast.Out(1)).To(downloadHtmlFlow.Inlet);

                builder.From(s.Outlet).To(sourceBroadcast.In);

                return(ClosedShape.Instance);
            });

            SourceActor = Context.Materializer().Materialize(graph);

            Receiving();
        }
예제 #5
0
        public void Reverse_Arrows_in_the_GraphDsl_must_work_across_a_Flow()
        {
            var task = RunnableGraph.FromGraph(GraphDsl.Create(Sink, (b, s) =>
            {
                b.To(s).Via(Flow.Create <int>().MapMaterializedValue(_ => MaterializedValue)).From(Source);
                return(ClosedShape.Instance);
            })).Run(Materializer);

            task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
            task.Result.Should().BeEquivalentTo(new[] { 1, 2, 3 });
        }
예제 #6
0
 public void A_Graph_should_build_simple_broadcast()
 {
     RunnableGraph.FromGraph(GraphDsl.Create(b =>
     {
         var broadcast = b.Add(new Broadcast <string>(2));
         b.From(In1).Via(F1).To(broadcast.In);
         b.From(broadcast.Out(0)).Via(F2).To(Out1);
         b.From(broadcast.Out(1)).Via(F3).To(Out2);
         return(ClosedShape.Instance);
     })).Run(Materializer);
 }
예제 #7
0
        private static BidiFlow <int, long, ByteString, string, Task <int> > BidiMaterialized()
        {
            return(BidiFlow.FromGraph(GraphDsl.Create(Sink.First <int>(), (b, s) =>
            {
                b.From(Source.Single(42).MapMaterializedValue(_ => Task.FromResult(0))).To(s);

                var top = b.Add(Flow.Create <int>().Select(x => ((long)x) + 2));
                var bottom = b.Add(Flow.Create <ByteString>().Select(x => x.ToString(Encoding.UTF8)));
                return new BidiShape <int, long, ByteString, string>(top.Inlet, top.Outlet, bottom.Inlet, bottom.Outlet);
            })));
        }
예제 #8
0
        public void UnzipWith_must_work_in_the_happy_case()
        {
            this.AssertAllStagesStopped(() =>
            {
                var leftProbe  = this.CreateManualSubscriberProbe <int>();
                var rightProbe = this.CreateManualSubscriberProbe <string>();

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var unzip  = b.Add(new UnzipWith <int, int, string>(Zipper));
                    var source = Source.From(Enumerable.Range(1, 4));

                    b.From(source).To(unzip.In);
                    b.From(unzip.Out0)
                    .Via(Flow.Create <int>().Buffer(4, OverflowStrategy.Backpressure))
                    .To(Sink.FromSubscriber(leftProbe));
                    b.From(unzip.Out1)
                    .Via(Flow.Create <string>().Buffer(4, OverflowStrategy.Backpressure))
                    .To(Sink.FromSubscriber(rightProbe));

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

                var leftSubscription  = leftProbe.ExpectSubscription();
                var rightSubscription = rightProbe.ExpectSubscription();

                leftSubscription.Request(2);
                rightSubscription.Request(1);

                leftProbe.ExpectNext(2, 4);
                leftProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(100));

                rightProbe.ExpectNext("1+1");
                rightProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(100));

                leftSubscription.Request(1);
                rightSubscription.Request(2);

                leftProbe.ExpectNext(6);
                leftProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(100));

                rightProbe.ExpectNext("2+2", "3+3");
                rightProbe.ExpectNoMsg(TimeSpan.FromMilliseconds(100));

                leftSubscription.Request(1);
                rightSubscription.Request(1);

                leftProbe.ExpectNext(8);
                rightProbe.ExpectNext("4+4");

                leftProbe.ExpectComplete();
                rightProbe.ExpectComplete();
            }, Materializer);
        }
예제 #9
0
        public void ActorGraphInterpreter_should_be_able_to_properly_handle_case_where_a_stage_fails_before_subscription_happens()
        {
            // Fuzzing needs to be off, so that the failure can propagate to the output boundary
            // before the ExposedPublisher message.
            var noFuzzMaterializer = ActorMaterializer.Create(Sys,
                                                              ActorMaterializerSettings.Create(Sys).WithFuzzingMode(false));

            this.AssertAllStagesStopped(() =>
            {
                var evilLatch = new CountdownEvent(1);

                // This is a somewhat tricky test setup. We need the following conditions to be met:
                //  - the stage should fail its output port before the ExposedPublisher message is processed
                //  - the enclosing actor (and therefore the stage) should be kept alive until a stray SubscribePending arrives
                //    that has been enqueued after ExposedPublisher message has been enqueued, but before it has been processed
                //
                // To achieve keeping alive the stage for long enough, we use an extra input and output port and instead
                // of failing the stage, we fail only the output port under test.
                //
                // To delay the startup long enough, so both ExposedPublisher and SubscribePending are enqueued, we use an evil
                // latch to delay the preStart() (which in turn delays the enclosing actor's preStart).
                var failyStage = new FailyInPreStartGraphStage(evilLatch);

                var downstream0 = this.CreateSubscriberProbe <int>();
                var downstream1 = this.CreateSubscriberProbe <int>();

                var upstream = this.CreatePublisherProbe <int>();

                RunnableGraph.FromGraph(GraphDsl.Create(b =>
                {
                    var faily = b.Add(failyStage);

                    b.From(Source.FromPublisher(upstream)).To(faily.In);
                    b.From(faily.Out0).To(Sink.FromSubscriber(downstream0));
                    b.From(faily.Out1).To(Sink.FromSubscriber(downstream1));

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

                evilLatch.Signal();
                var ex = downstream0.ExpectSubscriptionAndError();
                ex.Should().BeOfType <TestException>();
                ex.Message.Should().Be("Test failure in PreStart");

                // if an NRE would happen due to unset exposedPublisher (see #19338), this would receive a failure instead
                // of the actual element
                downstream1.Request(1);
                upstream.SendNext(42);
                downstream1.ExpectNext(42);

                upstream.SendComplete();
                downstream1.ExpectComplete();
            }, noFuzzMaterializer);
        }
예제 #10
0
        public void Reverse_Arrows_in_the_GraphDsl_must_work_from_SinkShape()
        {
            var task = RunnableGraph.FromGraph(GraphDsl.Create(Sink, (b, s) =>
            {
                b.To(s).From(Source);
                return(ClosedShape.Instance);
            })).Run(Materializer);

            task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
            task.Result.ShouldAllBeEquivalentTo(new[] { 1, 2, 3 });
        }
예제 #11
0
 public void A_Graph_should_build_simple_merge()
 {
     RunnableGraph.FromGraph(GraphDsl.Create(b =>
     {
         var merge = b.Add(new Merge <string>(2));
         b.From(In1).Via(F1).To(merge.In(0));
         b.From(In2).Via(F2).To(merge.In(1));
         b.From(merge.Out).Via(F3).To(Out1);
         return(ClosedShape.Instance);
     })).Run(Materializer);
 }
예제 #12
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);
        }
예제 #13
0
 public void Reverse_Arrows_in_the_GraphDsl_must_not_work_from_Outlets()
 {
     RunnableGraph.FromGraph(
         GraphDsl.Create(b =>
     {
         var o = b.Add(Source).Outlet;
         b.Invoking(builder => ((dynamic)builder).To(o).From(Source))
         .ShouldThrow <RuntimeBinderException>();
         b.To(Sink).From(o);
         return(ClosedShape.Instance);
     }));
 }
예제 #14
0
        public void FlowGraphs_when_turned_into_flows_should_be_transformable_with_a_Pipe()
        {
            var probe = TestSubscriber.CreateManualProbe <int>(this);

            var flow =
                Flow.FromGraph(GraphDsl.Create(PartialGraph(),
                                               (b, partial) => new FlowShape <int, string>(partial.Inlet, partial.Outlet)));

            Source1.Via(flow).Select(int.Parse).To(Sink.FromSubscriber(probe)).Run(Materializer);

            ValidateProbe(probe, StandardRequests, StandardResult);
        }
예제 #15
0
        public void FlowGraphs_when_turned_into_sinks_should_work_with_a_Source_when_having_KeyedSink_inside()
        {
            var probe   = TestSubscriber.CreateManualProbe <int>(this);
            var pubSink = Sink.AsPublisher <int>(false);

            var sink = Sink.FromGraph(GraphDsl.Create(pubSink, (b, p) => new SinkShape <int>(p.Inlet)));
            var mm   = Source1.RunWith(sink, Materializer);

            Source.FromPublisher(mm).To(Sink.FromSubscriber(probe)).Run(Materializer);

            ValidateProbe(probe, 4, new[] { 0, 1, 2, 3 });
        }
예제 #16
0
            internal static IGraph <ShufflePorts, NotUsed> Create <TIn, TOut>(Flow <TIn, TOut, NotUsed> pipeline)
            {
                return(GraphDsl.Create(b =>
                {
                    var merge = b.Add(new Merge <TIn>(2));
                    var balance = b.Add(new Balance <TOut>(2));

                    b.From(merge.Out).Via(pipeline).To(balance.In);

                    return new ShufflePorts(merge.In(0), merge.In(1), balance.Out(0), balance.Out(1));
                }));
            }
예제 #17
0
        public void ActorPublisher_should_work_in_a_GraphDsl()
        {
            var materializer = Sys.Materializer();
            var probe1       = CreateTestProbe();
            var probe2       = CreateTestProbe();

            var senderRef1 = ActorOf(Sender.Props);
            var source1    = Source.FromPublisher(ActorPublisher.Create <int>(senderRef1))
                             .MapMaterializedValue(_ => senderRef1);

            var sink1 = Sink.FromSubscriber(ActorSubscriber.Create <string>(ActorOf(Receiver.Props(probe1.Ref))))
                        .MapMaterializedValue(_ => probe1.Ref);
            var sink2 = Sink.ActorSubscriber <string>(Receiver.Props(probe2.Ref))
                        .MapMaterializedValue(_ => probe2.Ref);
            var senderRef2 = RunnableGraph.FromGraph(GraphDsl.Create(
                                                         Source.ActorPublisher <int>(Sender.Props),
                                                         (builder, source2) =>
            {
                var merge = builder.Add(new Merge <int, int>(2));
                var bcast = builder.Add(new Broadcast <string>(2));

                builder.From(source1).To(merge.In(0));
                builder.From(source2.Outlet).To(merge.In(1));

                builder.From(merge.Out).Via(Flow.Create <int>().Select(i => i.ToString())).To(bcast.In);

                builder.From(bcast.Out(0)).Via(Flow.Create <string>().Select(s => s + "mark")).To(sink1);
                builder.From(bcast.Out(1)).To(sink2);

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

            // the scala test is wrong
            const int noOfMessages = 10;

            for (var i = 0; i < noOfMessages; i++)
            {
                senderRef1.Tell(i);
                senderRef2.Tell(i + noOfMessages);
            }

            var probe1Messages = new List <string>(noOfMessages * 2);
            var probe2Messages = new List <string>(noOfMessages * 2);

            for (var i = 0; i < noOfMessages * 2; i++)
            {
                probe1Messages.Add(probe1.ExpectMsg <string>());
                probe2Messages.Add(probe2.ExpectMsg <string>());
            }
            probe1Messages.Should().BeEquivalentTo(Enumerable.Range(0, noOfMessages * 2).Select(i => i + "mark"));
            probe2Messages.Should().BeEquivalentTo(Enumerable.Range(0, noOfMessages * 2).Select(i => i.ToString()));
        }
예제 #18
0
        public void A_Graph_should_build_broadcast_merge()
        {
            RunnableGraph.FromGraph(GraphDsl.Create(b =>
            {
                var merge     = b.Add(new Merge <string>(2));
                var broadcast = b.Add(new Broadcast <string>(2));

                b.From(In1).Via(F1).Via(broadcast).Via(F2).Via(merge).Via(F3).To(Out1);
                b.From(broadcast).Via(F4).To(merge);

                return(ClosedShape.Instance);
            })).Run(Materializer);
        }
예제 #19
0
        public void A_Graph_with_materialized_value_must_work_also_when_the_sources_module_is_copied()
        {
            var foldFlow = Flow.FromGraph(GraphDsl.Create(Sink.Aggregate <int, int>(0, (sum, i) => sum + i), (b, fold) =>
            {
                var o = b.From(b.MaterializedValue).Via(Flow.Create <Task <int> >().SelectAsync(4, x => x));
                return(new FlowShape <int, int>(fold.Inlet, o.Out));
            }));

            var t = Source.From(Enumerable.Range(1, 10)).Via(foldFlow).RunWith(Sink.First <int>(), Materializer);

            t.Wait(TimeSpan.FromSeconds(3)).Should().BeTrue();
            t.Result.Should().Be(55);
        }
예제 #20
0
        public void A_Graph_should_suitably_override_attribute_handling_methods()
        {
            var ga = GraphDsl.Create(b =>
            {
                var id = b.Add(GraphStages.Identity <int>());
                return(new FlowShape <int, int>(id.Inlet, id.Outlet));
            }).Async().AddAttributes(Attributes.None).Named("useless");

            ga.Module.Attributes.GetFirstAttribute <Attributes.Name>().Value.Should().Be("useless");
            ga.Module.Attributes.GetFirstAttribute <Attributes.AsyncBoundary>()
            .Should()
            .Be(Attributes.AsyncBoundary.Instance);
        }
예제 #21
0
        static void Main(string[] args)
        {
            var tweetSource  = Source.ActorRef <ITweet>(100, OverflowStrategy.DropHead);
            var formatFlow   = Flow.Create <ITweet>().Select(FormatTweet);
            var writeSink    = Sink.ForEach <string>(Console.WriteLine);
            var countauthors = Flow.Create <ITweet>()
                               .StatefulSelectMany(() =>
            {
                var dict = new Dictionary <string, int>();

                Func <ITweet, IEnumerable <string> > result = (tweet =>
                {
                    var user = tweet.CreatedBy.Name;
                    if (!dict.ContainsKey(user))
                    {
                        dict.Add(user, 1);
                    }

                    return(new[] { $"{dict[user]++} tweet from {user}\n" });
                });

                return(result);
            });

            var graph = GraphDsl.Create(countauthors, writeSink, (notUsed, _) => notUsed, (b, count, write) =>
            {
                var broadcast = b.Add(new Broadcast <ITweet>(2));
                var output    = b.From(broadcast.Out(0)).Via(formatFlow);
                b.From(broadcast.Out(1)).Via(count).To(write);
                return(new FlowShape <ITweet, string>(broadcast.In, output.Out));
            });

            using (var sys = ActorSystem.Create("Reactive-Tweets"))
            {
                using (var mat = sys.Materializer())
                {
                    // Start Akka.Net stream
                    var actor = tweetSource.Via(graph).To(writeSink).Run(mat);

                    // Start Twitter stream
                    Auth.SetCredentials(new TwitterCredentials(ConsumerKey, ConsumerSecret, AccessToken,
                                                               AccessTokenSecret));
                    var stream = Stream.CreateFilteredStream();
                    stream.AddLocation(CenterOfNewYork);
                    stream.MatchingTweetReceived += (_, arg) => actor.Tell(arg.Tweet); // push the tweets into the stream
                    stream.StartStreamMatchingAllConditions();

                    Console.ReadLine();
                }
            }
        }
예제 #22
0
 /// <summary>
 /// Fusing graphs that have cycles involving FanIn stages might lead to deadlocks if
 /// demand is not carefully managed.
 ///
 /// This means that FanIn stages need to early pull every relevant input on startup.
 /// This can either be implemented inside the stage itself, or this method can be used,
 /// which adds a detacher stage to every input.
 /// </summary>
 /// <typeparam name="T">TBD</typeparam>
 /// <param name="stage">TBD</param>
 /// <returns>TBD</returns>
 internal static IGraph <UniformFanInShape <T, T>, NotUsed> WithDetachedInputs <T>(GraphStage <UniformFanInShape <T, T> > stage)
 {
     return(GraphDsl.Create(builder =>
     {
         var concat = builder.Add(stage);
         var detachers = concat.Ins.Select(inlet =>
         {
             var detacher = builder.Add(new Detacher <T>());
             builder.From(detacher).To(inlet);
             return detacher.Inlet;
         }).ToArray();
         return new UniformFanInShape <T, T>(concat.Out, detachers);
     }));
 }
예제 #23
0
        public void A_Graph_should_make_it_optional_to_specify_flows()
        {
            RunnableGraph.FromGraph(GraphDsl.Create(b =>
            {
                var merge     = b.Add(new Merge <string>(2));
                var broadcast = b.Add(new Broadcast <string>(2));

                b.From(In1).Via(merge).Via(broadcast).To(Out1);
                b.From(In2).To(merge);
                b.From(broadcast).To(Out2);

                return(ClosedShape.Instance);
            })).Run(Materializer);
        }
예제 #24
0
        public void FlowGraphs_when_turned_into_flows_should_work_with_a_Source_and_Sink()
        {
            var probe = TestSubscriber.CreateManualProbe <int>(this);

            var flow = Flow.FromGraph(GraphDsl.Create(PartialGraph(), (b, partial) =>
            {
                var o = b.From(partial.Outlet).Via(Flow.Create <string>().Select(int.Parse));
                return(new FlowShape <int, int>(partial.Inlet, o.Out));
            }));

            Source1.Via(flow).To(Sink.FromSubscriber(probe)).Run(Materializer);

            ValidateProbe(probe, StandardRequests, StandardResult);
        }
예제 #25
0
        public void GraphDSLs_when_turned_into_sinks_should_work_with_a_Source()
        {
            var probe = this.CreateManualSubscriberProbe <int>();

            var sink = Sink.FromGraph(GraphDsl.Create(PartialGraph(), (b, partial) =>
            {
                b.From(partial.Outlet).Via(Flow.Create <string>().Select(int.Parse)).To(Sink.FromSubscriber(probe));
                return(new SinkShape <int>(partial.Inlet));
            }));

            Source1.To(sink).Run(Materializer);

            ValidateProbe(probe, StandardRequests, StandardResult);
        }
예제 #26
0
        public void Reverse_Arrows_in_the_GraphDsl_must_work_towards_UniformFanOutShape()
        {
            var task = RunnableGraph.FromGraph(GraphDsl.Create(Sink, (b, s) =>
            {
                var f = b.Add(new Broadcast <int>(2));
                b.To(s).From(f);
                b.To(Streams.Dsl.Sink.Ignore <int>().MapMaterializedValue(_ => MaterializedValue)).From(f);
                b.From(Source).To(f);
                return(ClosedShape.Instance);
            })).Run(Materializer);

            task.Wait(TimeSpan.FromSeconds(1)).Should().BeTrue();
            task.Result.ShouldAllBeEquivalentTo(new[] { 1, 2, 3 });
        }
        private void GenerateReportAsync(OpenLogFileViewModel viewModel)
        {
            logFileRptGeneratorService.InitializeReport();

            viewModel.OverallProgress    = 0;
            viewModel.IsGeneratingReport = true;

            //var sourceQueue = Source.Queue<LogRptDto>(int.MaxValue, OverflowStrategy.Fail)
            //                                           .SelectAsyncUnordered(int.MaxValue, l => logFileRptGeneratorService.GetCheckInforInUseOuts(l, viewModel.LogFiles))
            //                                           .To(Sink.ActorRef<Tuple<bool, LogRptDto>>(logFilesExcelProviderActor, logFileRptGeneratorService.GetReportRows()))
            //                                           .Run(Context.Materializer());

            var g = RunnableGraph.FromGraph(GraphDsl.Create(b =>
            {
                var source = Source.From(viewModel.LogFiles);

                var sink = Sink.ActorRef <Tuple <bool, LogRptDto> >(logFilesExcelProviderActor, logFileRptGeneratorService.GetReportRows());

                var parsing = Flow.Create <LogFile>()
                              .Select(x =>
                {
                    viewModel.OverallProgress++;
                    var parseTask = logFilesParsingService.ParseLogFileEventsAsync(x);
                    parseTask.ContinueWith(t => denialsRptGeneratorService.Aggregate(t.Result));
                    return(parseTask.Result);
                }).WatchTermination((_, o) => { o.ContinueWith(t => getCheckInsActor.Tell(viewModel)); return(_); });
                //.WatchTermination((_,u)=>u.PipeTo(getCheckInsActor));
                //TODO: create new actor to run getCheckIns                ===^
                //Akka.Done
                //Akka.Actor.Status.Failure;
                var reportGen = Flow.Create <LogFile>()
                                .SelectAsyncUnordered(int.MaxValue, logFileRptGeneratorService.GenerateReport)
                                .Recover(exception =>
                {
                    throw exception;
                })
                                .SelectMany(x => x);
                //var getCheckIns = Flow.Create<LogRptDto>()
                //                        .SelectAsyncUnordered(int.MaxValue, x => getCheckInsActor.Tell(x))

                //var getCheckIns = Flow.Create<LogRptDto>()
                //                .SelectAsyncUnordered(int.MaxValue, l => logFileRptGeneratorService.GetCheckInforInUseOuts(l, viewModel.LogFiles));

                b.From(source).Via(parsing).Via(reportGen).To(Sink.ForEach <LogRptDto>(l => getCheckInsActor.Tell(l)));//.Via(getCheckIns).To(sink);

                return(ClosedShape.Instance);
            }));

            g.Run(Context.Materializer());
        }
예제 #28
0
        private static void Example2(ActorMaterializer materializer)
        {
            var graph = RunnableGraph.FromGraph(GraphDsl.Create(b =>
            {
                var source      = b.Add(Source.Single(new Uri("http://getakka.net/")));
                var sink        = b.Add(Sink.ForEach <Uri>(Console.WriteLine));
                var crawlerFlow = b.Add(WebCrawler());

                b.From(source).Via(crawlerFlow).To(sink);

                return(ClosedShape.Instance);
            }));

            graph.Run(materializer);
        }
예제 #29
0
        private static Flow <TIn, TOut, NotUsed> Balancer <TIn, TOut>(Flow <TIn, TOut, NotUsed> worker, int workerCount)
        {
            return(Flow.FromGraph(GraphDsl.Create(b =>
            {
                var balancer = b.Add(new Balance <TIn>(workerCount, waitForAllDownstreams: true));
                var merge = b.Add(new Merge <TOut>(workerCount));

                for (var i = 0; i < workerCount; i++)
                {
                    b.From(balancer).Via(worker.Async()).To(merge);
                }

                return new FlowShape <TIn, TOut>(balancer.In, merge.Out);
            })));
        }
예제 #30
0
        private static void Main(string[] args)
        {
            var source0 =
                Source.ActorPublisher <User>(ApiActorPublisher <User> .Props(@"http://*****:*****@"http://localhost:5000/api/properties"))
                .Select(x => new UserTuple(null, x, null));
            var source2 =
                Source.ActorPublisher <UserAuthTypes>(
                    ApiActorPublisher <UserAuthTypes> .Props(@"http://localhost:5000/api/auth"))
                .Select(x => new UserTuple(null, null, x));


            var graph = RunnableGraph.FromGraph(GraphDsl.Create(b =>
            {
                var merge      = b.Add(new Merge <UserTuple>(3));
                var s0         = b.Add(source0);
                var s1         = b.Add(source1);
                var s2         = b.Add(source2);
                var throttling = Flow.Create <Account>()
                                 .Throttle(1, TimeSpan.FromMilliseconds(500), 1, ThrottleMode.Shaping);

                var acc = Flow.Create <UserTuple>()
                          .Via(new KeyAccumulator <UserTuple, int?, Account>(
                                   keySelector: x => x.Id(),
                                   flushWhen: buffer => buffer.IsReady(),
                                   mapper: buffer => buffer.Map()));

                var sink = b.Add(Sink.ForEach <Account>(Console.WriteLine));

                b.From(s0).To(merge.In(0));
                b.From(s1).To(merge.In(1));
                b.From(s2).To(merge.In(2));
                b.From(merge.Out).Via(acc).Via(throttling).To(sink);

                return(ClosedShape.Instance);
            }));

            using (var system = ActorSystem.Create("system"))
                using (var materializer = system.Materializer())
                {
                    graph.Run(materializer);

                    Console.ReadLine();
                }
        }
예제 #31
0
 public UnzipWithFixture(GraphDsl.Builder<NotUsed> builder)
 {
     var unzip = builder.Add(new UnzipWith<int, int, string>(i => Tuple.Create(i + i, i + "+" + i)));
     In = unzip.In;
     Left = unzip.Out0;
     Right = unzip.Out1;
 }