我有以下代码示例,工作正常。我想添加一些更改来保持请求和响应之间的关系。我怎么能这样啊?
Rest api flow的具体化值为NotUsed
。有可能以某种方式使用Keep.both
吗?
// this flow is provided by some third party library that I can't change in place
val someRestApiFlow: Flow[Int, Int, NotUsed] = Flow[Int].mapAsync(10)(x => Future(x + 1))
val digits: Source[Int, NotUsed] = Source(List(1, 2, 3))
val r = digits.via(someRestApiFlow).runForeach(println)
结果是
2
3
4
我希望结果像
1 -> 2
2 -> 3
3 -> 4
答案 0 :(得分:1)
我也遇到过几次这种情况。我找到的唯一解决方案是使用DSL创建图表并使用broadcast
和zip
阶段。
import akka.actor.ActorSystem
import akka.stream.scaladsl.{Broadcast, Flow, GraphDSL, RunnableGraph, Sink, Source, Zip}
import akka.stream.{ActorMaterializer, ClosedShape}
import akka.{Done, NotUsed}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
object Main extends App {
implicit val system: ActorSystem = ActorSystem("my-system")
implicit val materializer: ActorMaterializer = ActorMaterializer()
val graph = RunnableGraph.fromGraph(GraphDSL.create() { implicit builder: GraphDSL.Builder[NotUsed] =>
import GraphDSL.Implicits._
val src: Source[Int, NotUsed] = Source(List(1, 2, 3))
val someRestApiFlow: Flow[Int, Int, NotUsed] = Flow[Int].mapAsync(10)(x => Future(x + 1))
val out: Sink[(Int, Int), Future[Done]] = Sink.foreach[(Int, Int)](println)
val bcast = builder.add(Broadcast[Int](2))
val zip = builder.add(Zip[Int, Int])
src ~> bcast ~> zip.in0
bcast ~> someRestApiFlow ~> zip.in1
zip.out ~> out
ClosedShape
})
graph.run()
}
这里正在做的是我们正在广播zip和自定义流的输入,并且该zip还等待自定义流的结果,最后将它们合并到发送接收器。
答案 1 :(得分:1)
您可以使用广播元素创建2个单独的流。广播的第一个输出通过someRestApiFlow
,广播的第二个输出未经修改。然后使用广播流的第二个输出将someRestApiFlow
的输出压缩。这样做,你有输入元素和通过someRestApiFlow
转换的结果。
digits ---> broadcast --> someRestApiFlow ---> zip --> result
\----------------------/