Rename RunnableFlow to RunnableGraph
This commit is contained in:
parent
7879a5521b
commit
c7a974dd1e
23 changed files with 102 additions and 102 deletions
|
|
@ -35,8 +35,8 @@ class FlowDocSpec extends AkkaSpec {
|
|||
val source = Source(1 to 10)
|
||||
val sink = Sink.fold[Int, Int](0)(_ + _)
|
||||
|
||||
// connect the Source to the Sink, obtaining a RunnableFlow
|
||||
val runnable: RunnableFlow[Future[Int]] = source.toMat(sink)(Keep.right)
|
||||
// connect the Source to the Sink, obtaining a RunnableGraph
|
||||
val runnable: RunnableGraph[Future[Int]] = source.toMat(sink)(Keep.right)
|
||||
|
||||
// materialize the flow and get the value of the FoldSink
|
||||
val sum: Future[Int] = runnable.run()
|
||||
|
|
@ -56,9 +56,9 @@ class FlowDocSpec extends AkkaSpec {
|
|||
|
||||
"materialization is unique" in {
|
||||
//#stream-reuse
|
||||
// connect the Source to the Sink, obtaining a RunnableFlow
|
||||
// connect the Source to the Sink, obtaining a RunnableGraph
|
||||
val sink = Sink.fold[Int, Int](0)(_ + _)
|
||||
val runnable: RunnableFlow[Future[Int]] =
|
||||
val runnable: RunnableGraph[Future[Int]] =
|
||||
Source(1 to 10).toMat(sink)(Keep.right)
|
||||
|
||||
// get the materialized value of the FoldSink
|
||||
|
|
@ -162,11 +162,11 @@ class FlowDocSpec extends AkkaSpec {
|
|||
val sink: Sink[Int, Future[Int]] = Sink.head[Int]
|
||||
|
||||
// By default, the materialized value of the leftmost stage is preserved
|
||||
val r1: RunnableFlow[Promise[Unit]] = source.via(flow).to(sink)
|
||||
val r1: RunnableGraph[Promise[Unit]] = source.via(flow).to(sink)
|
||||
|
||||
// Simple selection of materialized values by using Keep.right
|
||||
val r2: RunnableFlow[Cancellable] = source.viaMat(flow)(Keep.right).to(sink)
|
||||
val r3: RunnableFlow[Future[Int]] = source.via(flow).toMat(sink)(Keep.right)
|
||||
val r2: RunnableGraph[Cancellable] = source.viaMat(flow)(Keep.right).to(sink)
|
||||
val r3: RunnableGraph[Future[Int]] = source.via(flow).toMat(sink)(Keep.right)
|
||||
|
||||
// Using runWith will always give the materialized values of the stages added
|
||||
// by runWith() itself
|
||||
|
|
@ -175,21 +175,21 @@ class FlowDocSpec extends AkkaSpec {
|
|||
val r6: (Promise[Unit], Future[Int]) = flow.runWith(source, sink)
|
||||
|
||||
// Using more complext combinations
|
||||
val r7: RunnableFlow[(Promise[Unit], Cancellable)] =
|
||||
val r7: RunnableGraph[(Promise[Unit], Cancellable)] =
|
||||
source.viaMat(flow)(Keep.both).to(sink)
|
||||
|
||||
val r8: RunnableFlow[(Promise[Unit], Future[Int])] =
|
||||
val r8: RunnableGraph[(Promise[Unit], Future[Int])] =
|
||||
source.via(flow).toMat(sink)(Keep.both)
|
||||
|
||||
val r9: RunnableFlow[((Promise[Unit], Cancellable), Future[Int])] =
|
||||
val r9: RunnableGraph[((Promise[Unit], Cancellable), Future[Int])] =
|
||||
source.viaMat(flow)(Keep.both).toMat(sink)(Keep.both)
|
||||
|
||||
val r10: RunnableFlow[(Cancellable, Future[Int])] =
|
||||
val r10: RunnableGraph[(Cancellable, Future[Int])] =
|
||||
source.viaMat(flow)(Keep.right).toMat(sink)(Keep.both)
|
||||
|
||||
// It is also possible to map over the materialized values. In r9 we had a
|
||||
// doubly nested pair, but we want to flatten it out
|
||||
val r11: RunnableFlow[(Promise[Unit], Cancellable, Future[Int])] =
|
||||
val r11: RunnableGraph[(Promise[Unit], Cancellable, Future[Int])] =
|
||||
r9.mapMaterializedValue {
|
||||
case ((promise, cancellable), future) =>
|
||||
(promise, cancellable, future)
|
||||
|
|
@ -204,7 +204,7 @@ class FlowDocSpec extends AkkaSpec {
|
|||
future.map(_ + 3)
|
||||
|
||||
// The result of r11 can be also achieved by using the Graph API
|
||||
val r12: RunnableFlow[(Promise[Unit], Cancellable, Future[Int])] =
|
||||
val r12: RunnableGraph[(Promise[Unit], Cancellable, Future[Int])] =
|
||||
FlowGraph.closed(source, flow, sink)((_, _, _)) { implicit builder =>
|
||||
(src, f, dst) =>
|
||||
import FlowGraph.Implicits._
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
package docs.stream
|
||||
|
||||
import akka.stream.ActorMaterializer
|
||||
import akka.stream.scaladsl.{ RunnableFlow, Sink, Source, Flow, Keep }
|
||||
import akka.stream.scaladsl.{ RunnableGraph, Sink, Source, Flow, Keep }
|
||||
import akka.stream.stage.PushPullStage
|
||||
import akka.stream.testkit.AkkaSpec
|
||||
import org.scalatest.concurrent.{ ScalaFutures, Futures }
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ class IntegrationDocSpec extends AkkaSpec(IntegrationDocSpec.config) {
|
|||
//#email-addresses-mapAsync
|
||||
|
||||
//#send-emails
|
||||
val sendEmails: RunnableFlow[Unit] =
|
||||
val sendEmails: RunnableGraph[Unit] =
|
||||
emailAddresses
|
||||
.mapAsync(4)(address => {
|
||||
emailServer.send(
|
||||
|
|
@ -196,7 +196,7 @@ class IntegrationDocSpec extends AkkaSpec(IntegrationDocSpec.config) {
|
|||
.mapAsyncUnordered(4)(author => addressSystem.lookupEmail(author.handle))
|
||||
.collect { case Some(emailAddress) => emailAddress }
|
||||
|
||||
val sendEmails: RunnableFlow[Unit] =
|
||||
val sendEmails: RunnableGraph[Unit] =
|
||||
emailAddresses
|
||||
.mapAsyncUnordered(4)(address => {
|
||||
emailServer.send(
|
||||
|
|
@ -231,7 +231,7 @@ class IntegrationDocSpec extends AkkaSpec(IntegrationDocSpec.config) {
|
|||
//#blocking-mapAsync
|
||||
val blockingExecutionContext = system.dispatchers.lookup("blocking-dispatcher")
|
||||
|
||||
val sendTextMessages: RunnableFlow[Unit] =
|
||||
val sendTextMessages: RunnableGraph[Unit] =
|
||||
phoneNumbers
|
||||
.mapAsync(4)(phoneNo => {
|
||||
Future {
|
||||
|
|
@ -271,7 +271,7 @@ class IntegrationDocSpec extends AkkaSpec(IntegrationDocSpec.config) {
|
|||
smsServer.send(TextMessage(to = phoneNo, body = "I like your tweet"))
|
||||
}
|
||||
.withAttributes(ActorAttributes.dispatcher("blocking-dispatcher"))
|
||||
val sendTextMessages: RunnableFlow[Unit] =
|
||||
val sendTextMessages: RunnableGraph[Unit] =
|
||||
phoneNumbers.via(send).to(Sink.ignore)
|
||||
|
||||
sendTextMessages.run()
|
||||
|
|
@ -294,7 +294,7 @@ class IntegrationDocSpec extends AkkaSpec(IntegrationDocSpec.config) {
|
|||
val akkaTweets: Source[Tweet, Unit] = tweets.filter(_.hashtags.contains(akka))
|
||||
|
||||
implicit val timeout = Timeout(3.seconds)
|
||||
val saveTweets: RunnableFlow[Unit] =
|
||||
val saveTweets: RunnableGraph[Unit] =
|
||||
akkaTweets
|
||||
.mapAsync(4)(tweet => database ? Save(tweet))
|
||||
.to(Sink.ignore)
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ class TwitterStreamQuickstartDocSpec extends AkkaSpec {
|
|||
//#tweets-fold-count
|
||||
val sumSink: Sink[Int, Future[Int]] = Sink.fold[Int, Int](0)(_ + _)
|
||||
|
||||
val counter: RunnableFlow[Future[Int]] = tweets.map(t => 1).toMat(sumSink)(Keep.right)
|
||||
val counter: RunnableGraph[Future[Int]] = tweets.map(t => 1).toMat(sumSink)(Keep.right)
|
||||
|
||||
val sum: Future[Int] = counter.run()
|
||||
|
||||
|
|
@ -176,20 +176,20 @@ class TwitterStreamQuickstartDocSpec extends AkkaSpec {
|
|||
|
||||
//#tweets-runnable-flow-materialized-twice
|
||||
val sumSink = Sink.fold[Int, Int](0)(_ + _)
|
||||
val counterRunnableFlow: RunnableFlow[Future[Int]] =
|
||||
val counterRunnableGraph: RunnableGraph[Future[Int]] =
|
||||
tweetsInMinuteFromNow
|
||||
.filter(_.hashtags contains akka)
|
||||
.map(t => 1)
|
||||
.toMat(sumSink)(Keep.right)
|
||||
|
||||
// materialize the stream once in the morning
|
||||
val morningTweetsCount: Future[Int] = counterRunnableFlow.run()
|
||||
val morningTweetsCount: Future[Int] = counterRunnableGraph.run()
|
||||
// and once in the evening, reusing the flow
|
||||
val eveningTweetsCount: Future[Int] = counterRunnableFlow.run()
|
||||
val eveningTweetsCount: Future[Int] = counterRunnableGraph.run()
|
||||
|
||||
//#tweets-runnable-flow-materialized-twice
|
||||
|
||||
val sum: Future[Int] = counterRunnableFlow.run()
|
||||
val sum: Future[Int] = counterRunnableGraph.run()
|
||||
|
||||
sum.map { c => println(s"Total tweets processed: $c") }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,14 +45,14 @@ Sink
|
|||
Flow
|
||||
A processing stage which has *exactly one input and output*, which connects its up- and downstreams by
|
||||
transforming the data elements flowing through it.
|
||||
RunnableFlow
|
||||
RunnableGraph
|
||||
A Flow that has both ends "attached" to a Source and Sink respectively, and is ready to be ``run()``.
|
||||
|
||||
It is possible to attach a ``Flow`` to a ``Source`` resulting in a composite source, and it is also possible to prepend
|
||||
a ``Flow`` to a ``Sink`` to get a new sink. After a stream is properly terminated by having both a source and a sink,
|
||||
it will be represented by the ``RunnableFlow`` type, indicating that it is ready to be executed.
|
||||
it will be represented by the ``RunnableGraph`` type, indicating that it is ready to be executed.
|
||||
|
||||
It is important to remember that even after constructing the ``RunnableFlow`` by connecting all the source, sink and
|
||||
It is important to remember that even after constructing the ``RunnableGraph`` by connecting all the source, sink and
|
||||
different processing stages, no data will flow through it until it is materialized. Materialization is the process of
|
||||
allocating all resources needed to run the computation described by a Flow (in Akka Streams this will often involve
|
||||
starting up Actors). Thanks to Flows being simply a description of the processing pipeline they are *immutable,
|
||||
|
|
@ -61,7 +61,7 @@ one actor prepare the work, and then have it be materialized at some completely
|
|||
|
||||
.. includecode:: code/docs/stream/FlowDocSpec.scala#materialization-in-steps
|
||||
|
||||
After running (materializing) the ``RunnableFlow[T]`` we get back the materialized value of type T. Every stream processing
|
||||
After running (materializing) the ``RunnableGraph[T]`` we get back the materialized value of type T. Every stream processing
|
||||
stage can produce a materialized value, and it is the responsibility of the user to combine them to a new type.
|
||||
In the above example we used ``toMat`` to indicate that we want to transform the materialized value of the source and
|
||||
sink, and we used the convenience function ``Keep.right`` to say that we are only interested in the materialized value
|
||||
|
|
|
|||
|
|
@ -96,8 +96,8 @@ all of its different phases in different places and in the end connect them all
|
|||
|
||||
This can be achieved using ``FlowGraph.partial`` instead of
|
||||
``FlowGraph.closed``, which will return a ``Graph`` instead of a
|
||||
``RunnableFlow``. The reason of representing it as a different type is that a
|
||||
:class:`RunnableFlow` requires all ports to be connected, and if they are not
|
||||
``RunnableGraph``. The reason of representing it as a different type is that a
|
||||
:class:`RunnableGraph` requires all ports to be connected, and if they are not
|
||||
it will throw an exception at construction time, which helps to avoid simple
|
||||
wiring errors while working with graphs. A partial flow graph however allows
|
||||
you to return the set of yet to be connected ports from the code block that
|
||||
|
|
|
|||
|
|
@ -147,16 +147,16 @@ finally we connect the flow using ``toMat`` the previously prepared Sink. Rememb
|
|||
materialized. When you chain these together, you can explicitly combine their materialized values: in our example we
|
||||
used the ``Keep.right`` predefined function, which tells the implementation to only care about the materialized
|
||||
type of the stage currently appended to the right. As you can notice, the materialized type of sumSink is ``Future[Int]``
|
||||
and because of using ``Keep.right``, the resulting :class:`RunnableFlow` has also a type parameter of ``Future[Int]``.
|
||||
and because of using ``Keep.right``, the resulting :class:`RunnableGraph` has also a type parameter of ``Future[Int]``.
|
||||
|
||||
This step does *not* yet materialize the
|
||||
processing pipeline, it merely prepares the description of the Flow, which is now connected to a Sink, and therefore can
|
||||
be ``run()``, as indicated by its type: :class:`RunnableFlow[Future[Int]]`. Next we call ``run()`` which uses the implicit :class:`ActorMaterializer`
|
||||
to materialize and run the flow. The value returned by calling ``run()`` on a ``RunnableFlow[T]`` is of type ``T``.
|
||||
be ``run()``, as indicated by its type: :class:`RunnableGraph[Future[Int]]`. Next we call ``run()`` which uses the implicit :class:`ActorMaterializer`
|
||||
to materialize and run the flow. The value returned by calling ``run()`` on a ``RunnableGraph[T]`` is of type ``T``.
|
||||
In our case this type is ``Future[Int]`` which, when completed, will contain the total length of our tweets stream.
|
||||
In case of the stream failing, this future would complete with a Failure.
|
||||
|
||||
A :class:`RunnableFlow` may be reused
|
||||
A :class:`RunnableGraph` may be reused
|
||||
and materialized multiple times, because it is just the "blueprint" of the stream. This means that if we materialize a stream,
|
||||
for example one that consumes a live stream of tweets within a minute, the materialized values for those two materializations
|
||||
will be different, as illustrated by this example:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue