Akka Streams: What does Mat represents in Source[out, Mat]

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-17 16:27:40

问题


In Akka streams what does Mat in Source[Out, Mat] or Sink[In, Mat] represent. When will it actually be used?


回答1:


The Mat type parameter represents the type of the materialized value of this stream.

Remember that in Akka Source, Flow, Sink (well, all graphs) are just blueprints - they do not do any processing by themselves, they only describe how the stream should be constructed. The process of turning these blueprints into a working stream with live data is called materialization.

The core method for materializing a stream is called run(), and it is defined in the RunnableGraph class. All other methods to run a stream (e.g. runWith on a Sink or Source) eventually delegate to this method. You can see that this method returns Mat. That is, materializing a stream yields a materialized value.

For example, there is a sink which combines all the values in a stream into a single value, it is constructed with Sink.fold. But how do you get this value? Since the stream is running asynchronously, a natural type for this value would be Future[T], where T is the type of the fold accumulator. Turns out, Sink.fold returns Sink[In, Future[T]], that is, this Future[T] is its materialized value, therefore, when you materialize it, you get an instance of Future[T] which you can then use in your own code for further processing: it will complete with a value if the stream completes correctly and it will complete with a failure if the stream has terminated with an exception.

Each part of the graph you construct by combining sinks, sources and flows (and other kinds of graphs) may potentially have an associated materialized value. For example, materialized value of Source.queue is a queue which you can use to push elements to the stream once it is materialized, and materialized value of Sink.actorSubscriber is an ActorRef which you can use to interact with the actor (which is created by the materializer when the stream is materialized). On the other hand, there is Flow.map which is a flow with no meaningful materialized value (there is nothing you can externally control when you only apply a pure function to a stream), therefore its materialized value is NotUsed, which is essentially Unit.

Naturally, it is possible for different parts of stream contain their own materialized value. For example, nothing prevents you from combining Source.queue and Sink.fold. But RunnableGraph.run() can only return one materialized value. To overcome this, there are usually two variants of combining methods on Sinks, Flows, and other graphs, usually called like method and methodMat, e.g. to and toMat. The second variant allows you to choose how to combine materialized values of the streams you are joining. For example, you can put them into a tuple to get them both:

val (queue, future) = Source.queue[Int](10, OverflowStrategy.fail)
  .map(x => x + 10)
  .toMat(Sink.fold(0)(_ + _))(Keep.both)
  .run()

Default combination methods (without the Mat suffix) usually choose either the left or the right materialized value, depending on what would be the most natural thing to do for this particular kind of stream. The Keep object contains convenience methods which return either left, right or both arguments, specifically for the purpose of using them as the last argument for *Mat methods, but nothing prevents you from writing your own combining function.



来源:https://stackoverflow.com/questions/39727729/akka-streams-what-does-mat-represents-in-sourceout-mat

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