What is the purpose of the composite flow(from Sink and Source)?

大城市里の小女人 提交于 2019-12-13 03:59:14

问题


I am trying the understand composite flow (from Sink and Source) from the website and they represent as the following:

Could someone please provide an example for the usage of composite flow.
And when should I use it?


回答1:


Flow.fromSinkAndSource provides a convenient way to assemble a flow composed with a sink as its input and a source as its output that are not connected, which can be best illustrated with the following diagram (available in the API link):

  +----------------------------------------------+
  | Resulting Flow[I, O, NotUsed]                |
  |                                              |
  |  +---------+                  +-----------+  |
  |  |         |                  |           |  |
I ~~>| Sink[I] | [no-connection!] | Source[O] | ~~> O
  |  |         |                  |           |  |
  |  +---------+                  +-----------+  |
  +----------------------------------------------+

As shown in @gabrielgiussi's answer, it's often used in cases where one wants to "switch" the output of an existing source( or flow) to some different output - for testing purposes or what-not. Here's a trivialized example:

import akka.actor.ActorSystem
import akka.stream.scaladsl._
implicit val system = ActorSystem("system")
implicit val materializer = ActorMaterializer()

val switchFlow = Flow.fromSinkAndSource( Sink.ignore, Source(List("a", "b", "c")) )

Source(1 to 5).via(switchFlow).runForeach(println)
// res1: scala.concurrent.Future[akka.Done] = Future(Success(Done))
// a
// b
// c

It's also worth noting that the method's "Mat" version, fromSinkAndSourceMat, has some interesting use cases. An example is to use it to keep half-closed WebSockets open by using Source.maybe[T] to maintain a Promise[Option[T]] as the materialized value which will be completed when one wants to close the connection. Below is the sample code from the relevant section in the Akka-http WebSockets client support document:

// using Source.maybe materializes into a promise
// which will allow us to complete the source later
val flow: Flow[Message, Message, Promise[Option[Message]]] =
  Flow.fromSinkAndSourceMat(
    Sink.foreach[Message](println),
    Source.maybe[Message])(Keep.right)

val (upgradeResponse, promise) =
  Http().singleWebSocketRequest(
    WebSocketRequest("ws://example.com:8080/some/path"),
    flow)

// at some later time we want to disconnect
promise.success(None)



回答2:


Maybe in some scenario you just need to provide the Flow and for certain cases you need a NoOp Flow. Then you could do

Flow.fromSinkAndSource(Sink.ignore,Source.empty)

Or ignore every element from the Source and use another one

Flow.fromSinkAndSource(Sink.ignore,Source.tick(1.second,1.second,"something"))


来源:https://stackoverflow.com/questions/55669591/what-is-the-purpose-of-the-composite-flowfrom-sink-and-source

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!