在 Akka 流中,Mat in Source[Out, Mat] 或 Sink[In, Mat] 代表什么。什么时候会真正使用?
1 回答
Mat
type 参数表示此流的具体化值的类型。
请记住,在 AkkaSource
中Flow
,Sink
(嗯,所有的图)只是蓝图——它们自己不做任何处理,它们只描述应该如何构造流。将这些蓝图转化为具有实时数据的工作流的过程称为物化。
实现流的核心方法称为run()
,并在类中定义。RunnableGraph
运行流的所有其他方法(例如runWith
在 aSink
或上Source
)最终委托给该方法。可以看到这个方法返回Mat
. 也就是说,物化流会产生物化值。
例如,有一个接收器将流中的所有值组合成一个值,它是用Sink.fold
. 但是你如何得到这个值呢?由于流是异步运行的,因此该值的自然类型是Future[T]
,其中T
是折叠累加器的类型。结果是,Sink.fold
返回Sink[In, Future[T]]
,也就是说,这Future[T]
是它的物化值,因此,当你物化它时,你会得到一个实例,Future[T]
然后你可以在你自己的代码中使用它进行进一步处理:如果流正确完成,它将以一个值完成如果流因异常而终止,它将以失败告终。
您通过组合汇、源和流(以及其他类型的图)构建的图的每个部分都可能具有相关的物化值。例如,物化值Source.queue
是一个队列,一旦物化,您可以使用它将元素推送到流,物化值Sink.actorSubscriber
是ActorRef
您可以用来与参与者交互的一个(由物化器在流被创建时创建物化)。另一方面,有Flow.map
一个流没有有意义的物化值(当您仅将纯函数应用于流时,您无法从外部控制任何东西),因此它的物化值是NotUsed
,本质上是Unit
。
自然,流的不同部分可能包含它们自己的物化值。例如,没有什么可以阻止您组合Source.queue
and Sink.fold
。但RunnableGraph.run()
只能返回一个物化值。Sink
为了克服这个问题,在s、Flow
s 和其他图上通常有两种组合方法的变体,通常称为 like method
and 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
对象包含返回左、右或两个参数的便捷方法,专门用于将它们用作*Mat
方法的最后一个参数,但没有什么能阻止您编写自己的组合函数。