Play 2.5 Что такое akka.stream.Materializer полезен?

Недавно я начал использовать Play 2.5, и мне было интересно, что было сделано для следующего:

@Inject() (implicit val mat: Materializer)

У меня было несколько фрагментов кода, которые не работали и решили эту проблему, но я до сих пор не вижу, что делает материализатор.

Спасибо

Ответ 1

Средство материализации, создающее результаты graph

Материализатор делает actors выполнение графика для получения этих результатов.

Граф в его простейшей форме состоит из источника, который предоставляет элементы, и приемника, который потребляет элементы.

Здесь источник, который предоставляет диапазон целых чисел (в этом примере целые числа являются нашими элементами):

val source = Source(1 to 10)

И вот раковина, которая суммирует все целые числа, получаемые от источника:

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

Мы подключаем источник и приемник для получения графика:

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

Учтите, что никакие вычисления, добавление в нашем случае, не выполняются при создании графика. Код declarative, графики описывают, как мы хотим преобразовать наши данные, но это еще одно задание для фактического выполнения вычислений: Графы чертежи.

Теперь, как насчет материализатора? Материализатор принимает меры, когда мы запускаем график:

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

Когда мы run() на графике, материализатор берет граф и заставляет актеров выполнять преобразования данных, указанные в графе (в этом примере он добавляет целые числа).

Возможно, было бы полезно представить график в качестве чертежа для построения дома, материализатора, как мастера, который смотрит на чертеж, рассказывая строителям, как построить дом в соответствии с планом. Строители этой аналогии соответствуют актерам Акки.

Причина, по которой теперь работают несколько частей вашего кода, заключается в том, что с помощью материализатора вы предоставляете способ выполнения графиков. Графы в основном используются в Akka HTTP, который используется для использования 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 elements
  val sink = Sink.fold[Int, Int](0)(_ + _)

 /*
  * Connect source and sink.
  * Keep only the output values (i.e., the graph 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 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"))
}

Поместите libraryDependencies += "com.typesafe.akka" %% "akka-stream" % "2.5.3" в свой build.sbt, чтобы сделать библиотеку потока Akka доступной в вашем коде.

Здесь больше об источниках и стоках.