问题
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