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 }); }
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(); }
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 }); }
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); }
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); }))); }
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); }
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); }
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 }); }
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); }
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); }
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); })); }
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); }
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 }); }
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)); })); }
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())); }
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); }
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); }
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); }
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(); } } }
/// <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); })); }
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); }
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); }
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); }
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()); }
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); }
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); }))); }
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(); } }
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; }