/* * Copyright (C) 2015-2019 Lightbend Inc. */ package akka.stream import akka.stream.impl.fusing.GraphInterpreter import akka.stream.scaladsl._ import akka.stream.testkit.StreamSpec class FusingSpec extends StreamSpec { implicit val materializer = ActorMaterializer() def actorRunningStage = { GraphInterpreter.currentInterpreter.context } val snitchFlow = Flow[Int].map(x => { testActor ! actorRunningStage; x }).async "SubFusingActorMaterializer" must { "work with asynchronous boundaries in the subflows" in { val async = Flow[Int].map(_ * 2).async Source(0 to 9) .map(_ * 10) .flatMapMerge(5, i => Source(i to (i + 9)).via(async)) .grouped(1000) .runWith(Sink.head) .futureValue .sorted should ===(0 to 198 by 2) } "use multiple actors when there are asynchronous boundaries in the subflows (manual)" in { val async = Flow[Int].map(x => { testActor ! actorRunningStage; x }).async Source(0 to 9) .via(snitchFlow.async) .flatMapMerge(5, i => Source.single(i).via(async)) .grouped(1000) .runWith(Sink.head) .futureValue .sorted should ===(0 to 9) val refs = receiveN(20) refs.toSet should have size (11) // main flow + 10 subflows } "use multiple actors when there are asynchronous boundaries in the subflows (operator)" in { Source(0 to 9) .via(snitchFlow) .flatMapMerge(5, i => Source.single(i).via(snitchFlow.async)) .grouped(1000) .runWith(Sink.head) .futureValue .sorted should ===(0 to 9) val refs = receiveN(20) refs.toSet should have size (11) // main flow + 10 subflows } "use one actor per grouped substream when there is an async boundary around the flow (manual)" in { val in = 0 to 9 Source(in) .via(snitchFlow) .groupBy(in.size, identity) .via(snitchFlow.async) .mergeSubstreams .runWith(Sink.seq) .futureValue.sorted should ===(in) val refs = receiveN(in.size + in.size) // each element through the first map, then the second map refs.toSet should have size (in.size + 1) // outer/main actor + 1 actor per subflow } "use one actor per grouped substream when there is an async boundary around the flow (operator)" in { val in = 0 to 9 Source(in) .via(snitchFlow) .groupBy(in.size, identity) .via(snitchFlow) .async .mergeSubstreams .runWith(Sink.seq) .futureValue.sorted should ===(in) val refs = receiveN(in.size + in.size) // each element through the first map, then the second map refs.toSet should have size (in.size + 1) // outer/main actor + 1 actor per subflow } } }