Akka Streams:Mat 在 Source[out, Mat] 中代表什么
Akka Streams: What does Mat represents in Source[out, Mat]
在Akka流中,Source[Out, Mat]或Sink[In, Mat]中的Mat代表什么。什么时候真正使用它?
Mat
类型参数表示此流的物化值 的类型。
请记住,在 Akka 中 Source
、Flow
、Sink
(好吧,所有图形)都只是蓝图——它们自己不做任何处理,它们只描述如何应构建流。将这些蓝图变成具有实时数据的工作流的过程称为 实现。
实现流的核心方法称为run()
,在RunnableGraph
class中是defined。 运行 流的所有其他方法(例如 Sink
或 Source
上的 runWith
)最终委托给此方法。可以看到这个方法returns Mat
。也就是说,具体化一个流会产生一个具体化的值。
例如,有一个sink将流中的所有值组合成一个值,它是用Sink.fold
构造的。但是你如何获得这个值呢?由于流是 运行ning 异步的,因此该值的自然类型是 Future[T]
,其中 T
是折叠累加器的类型。原来,Sink.fold
returns Sink[In, Future[T]]
,也就是这个Future[T]
是它的物化值,所以,当你物化它的时候,你得到的是[=22=的一个实例] 然后您可以在自己的代码中使用它进行进一步处理:如果流正确完成,它将以一个值完成,如果流因异常终止,它将以失败完成。
您通过组合汇、源和流(以及其他类型的图)构建的图的每个部分都可能具有关联的物化值。例如,Source.queue
的物化值是一个队列,一旦它被物化,您就可以使用它来将元素推送到流中,而 Sink.actorSubscriber
的物化值是一个 ActorRef
,您可以使用它来与 actor 交互(在流被具体化时由 materializer 创建)。另一方面,Flow.map
是一个没有有意义物化值的流(当你只对流应用纯函数时,你无法从外部控制任何东西),因此它的物化值为 NotUsed
,本质上是 Unit
.
自然地,流的不同部分可能包含它们自己的物化值。例如,没有什么能阻止您组合 Source.queue
和 Sink.fold
。但是RunnableGraph.run()
只能return一个物化值。为了克服这个问题,在 Sink
s、Flow
s 和其他图上通常有两种组合方法的变体,通常称为 method
和 methodMat
,例如to
and toMat
。第二种变体允许您选择如何合并 您正在加入的流的物化值。例如,您可以将它们放入一个元组中以同时获取它们:
val (queue, future) = Source.queue[Int](10, OverflowStrategy.fail)
.map(x => x + 10)
.toMat(Sink.fold(0)(_ + _))(Keep.both)
.run()
默认组合方法(不带 Mat
后缀)通常选择左物化值或右物化值,这取决于对这种特定类型的流最自然的做法。 Keep
对象包含 return 左、右或两个参数的便捷方法,专门用于将它们用作 *Mat
方法的最后一个参数,但没有什么能阻止你编写你的自己的组合函数。
在Akka流中,Source[Out, Mat]或Sink[In, Mat]中的Mat代表什么。什么时候真正使用它?
Mat
类型参数表示此流的物化值 的类型。
请记住,在 Akka 中 Source
、Flow
、Sink
(好吧,所有图形)都只是蓝图——它们自己不做任何处理,它们只描述如何应构建流。将这些蓝图变成具有实时数据的工作流的过程称为 实现。
实现流的核心方法称为run()
,在RunnableGraph
class中是defined。 运行 流的所有其他方法(例如 Sink
或 Source
上的 runWith
)最终委托给此方法。可以看到这个方法returns Mat
。也就是说,具体化一个流会产生一个具体化的值。
例如,有一个sink将流中的所有值组合成一个值,它是用Sink.fold
构造的。但是你如何获得这个值呢?由于流是 运行ning 异步的,因此该值的自然类型是 Future[T]
,其中 T
是折叠累加器的类型。原来,Sink.fold
returns Sink[In, Future[T]]
,也就是这个Future[T]
是它的物化值,所以,当你物化它的时候,你得到的是[=22=的一个实例] 然后您可以在自己的代码中使用它进行进一步处理:如果流正确完成,它将以一个值完成,如果流因异常终止,它将以失败完成。
您通过组合汇、源和流(以及其他类型的图)构建的图的每个部分都可能具有关联的物化值。例如,Source.queue
的物化值是一个队列,一旦它被物化,您就可以使用它来将元素推送到流中,而 Sink.actorSubscriber
的物化值是一个 ActorRef
,您可以使用它来与 actor 交互(在流被具体化时由 materializer 创建)。另一方面,Flow.map
是一个没有有意义物化值的流(当你只对流应用纯函数时,你无法从外部控制任何东西),因此它的物化值为 NotUsed
,本质上是 Unit
.
自然地,流的不同部分可能包含它们自己的物化值。例如,没有什么能阻止您组合 Source.queue
和 Sink.fold
。但是RunnableGraph.run()
只能return一个物化值。为了克服这个问题,在 Sink
s、Flow
s 和其他图上通常有两种组合方法的变体,通常称为 method
和 methodMat
,例如to
and toMat
。第二种变体允许您选择如何合并 您正在加入的流的物化值。例如,您可以将它们放入一个元组中以同时获取它们:
val (queue, future) = Source.queue[Int](10, OverflowStrategy.fail)
.map(x => x + 10)
.toMat(Sink.fold(0)(_ + _))(Keep.both)
.run()
默认组合方法(不带 Mat
后缀)通常选择左物化值或右物化值,这取决于对这种特定类型的流最自然的做法。 Keep
对象包含 return 左、右或两个参数的便捷方法,专门用于将它们用作 *Mat
方法的最后一个参数,但没有什么能阻止你编写你的自己的组合函数。