播放2.5什么是akka.stream.Materializer有用吗?

时间:2016-04-27 11:19:35

标签: scala playframework

我最近开始使用Play 2.5,我想知道做以下事情的目的是什么:

@Inject() (implicit val mat: Materializer)

我有几段代码不能正常工作,并且由于这个问题解决了这个问题,但我仍然没有看到具体化工作者正在做什么。

由于

1 个答案:

答案 0 :(得分:27)

实现意味着产生graph

的结果

物化工具使actors执行图表以产生这些结果。

图形最简单的形式包括提供元素的源和消耗元素的接收器。

这是一个提供一系列整数的源(在本例中,整数是我们的元素):

val source = Source(1 to 10)

这是一个汇总,它汇总了从源获得的所有整数:

val sink = Sink.fold[Int, Int](0)(_ + _)

我们连接源和接收器以获取图表:

val graph = source.toMat(sink)(Keep.right)

请注意,在创建图形时,执行 no calculation ,在我们的例子中添加。 代码为declarative,图表描述了我们如何转换数据,但实际执行计算是其他人的工作:图形为blueprints

现在,物化器怎么样?当我们运行图表时,物料化器会采取措施:

implicit val materializer = ActorMaterializer()
val futureResult = graph.run()

当我们run()图形时,物化器采用图形并使actor执行图形中指定的数据转换;在这个例子中,那是添加整数。

将图形想象成建造房屋的蓝图,作为工头查看蓝图的材料,告诉建筑商如何根据蓝图实际建造房屋可能会有所帮助。这个类比中的建造者对应于阿卡的演员。

您的几个代码现在可以使用的原因是,使用Materializer,您可以提供执行图形的方法。图表在Akka HTTP中大量使用,其中Play用于HTTP请求和响应。

您在评论中提到的WSClient使用图表来执行请求,因此需要一个物化工具。

以下是创建和运行图表的完整示例:

import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.{Keep, Sink, Source}

object Graphs extends App {

  // The start of our simple graph. It provides elements, integers in our case
  val source = Source(1 to 10)

  // The end of our graph. It processes the source's elements
  val sink = Sink.fold[Int, Int](0)(_ + _)

 /*
  * Connect source and sink.
  * Keep only the output values (i.e., the graph's right side).
  * Note that this is declarative: no result is computed until we run the graph.
  */
  val graph = source.toMat(sink)(Keep.right)

  // The system coordinates actors and provides threads for them
  implicit val actorSystem = ActorSystem()
  // The materializer makes actors execute graphs
  implicit val materializer = ActorMaterializer()

  // Running the graph means that the materializer assigns actors to execute
  // the graph from start (source) to end (sink)
  val futureResult = graph.run()

  // Use the actor system's execution context, which provides threads,
  // to print the result of running the graph
  implicit val executionContext = actorSystem.dispatcher
  futureResult.foreach(res => println(s"Result of running the graph: $res"))

  actorSystem.terminate().foreach(_ => println("System is shut down"))
}

将它放在build.sbt中,以便在代码中提供Akka的流库:

libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.5.19"

Here's more关于来源和汇点。