From 7acdda1d1faa14552599897b164fac463159f617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Endre=20S=C3=A1ndor=20Varga?= Date: Thu, 26 Nov 2015 16:43:51 +0100 Subject: [PATCH] +str, doc: Documentation for GraphStage --- .../rst/images/inport_transitions.png | Bin 0 -> 67982 bytes .../rst/images/outport_transitions.png | Bin 0 -> 30528 bytes akka-docs-dev/rst/images/port_transitions.svg | 1054 +++++++++++++++++ .../rst/java/migration-guide-1.0-2.x-java.rst | 13 + akka-docs-dev/rst/java/stream-customize.rst | 224 +++- .../code/docs/stream/GraphStageDocSpec.scala | 86 ++ .../scala/migration-guide-1.0-2.x-scala.rst | 14 + akka-docs-dev/rst/scala/stream-customize.rst | 230 +++- akka-docs-dev/rst/scala/stream-testkit.rst | 19 + .../main/scala/akka/stream/javadsl/Flow.scala | 2 +- .../main/scala/akka/stream/stage/Stage.scala | 1 + 11 files changed, 1602 insertions(+), 41 deletions(-) create mode 100644 akka-docs-dev/rst/images/inport_transitions.png create mode 100644 akka-docs-dev/rst/images/outport_transitions.png create mode 100644 akka-docs-dev/rst/images/port_transitions.svg create mode 100644 akka-docs-dev/rst/scala/code/docs/stream/GraphStageDocSpec.scala diff --git a/akka-docs-dev/rst/images/inport_transitions.png b/akka-docs-dev/rst/images/inport_transitions.png new file mode 100644 index 0000000000000000000000000000000000000000..f5b6c179d1a0ed1739e39c04fbcf4bfe6d16ac17 GIT binary patch literal 67982 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 Q1_lNOPgg&ebxsLQ08NK`y#N3J literal 0 HcmV?d00001 diff --git a/akka-docs-dev/rst/images/outport_transitions.png b/akka-docs-dev/rst/images/outport_transitions.png new file mode 100644 index 0000000000000000000000000000000000000000..7eb407a464c02eb6467aacfbd1b302022e61859b GIT binary patch literal 30528 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
  • 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 + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + PUSHED + isAvailable + !hasBeenPulled + !isClosed + + + + PUSHED_EMPTY + !isAvailable + !hasBeenPulled + !isClosed + + + + PULLED + !isAvailable + hasBeenPulled + !isClosed + + + + CLOSED_EMPTY + !isAvailable + !hasBeenPulled + isClosed + + + grab() + + + pull() + onPush() + + + CLOSED + isAvailable + !hasBeenPulled + isClosed + + + + grab() + + + onUpstreamFinish() + cancel() + onUpstreamFailure() + onUpstreamFinish() + cancel() + onUpstreamFailure() + onUpstreamFinish() + cancel() + onUpstreamFailure() + + + PULLED + isAvailable + !isClosed + + + + + PUSHED + !isAvailable + !isClosed + + + + + + CLOSED + !isAvailable + isClosed + + + + + push(elem) + onPull() + + + complete()fail(ex)onDownstreamFinish() + + complete()fail(ex)onDownstreamFinish() + + + + cancel() + + cancel() + + complete()fail() + pull() + + diff --git a/akka-docs-dev/rst/java/migration-guide-1.0-2.x-java.rst b/akka-docs-dev/rst/java/migration-guide-1.0-2.x-java.rst index 5273332bed..4c453b54ef 100644 --- a/akka-docs-dev/rst/java/migration-guide-1.0-2.x-java.rst +++ b/akka-docs-dev/rst/java/migration-guide-1.0-2.x-java.rst @@ -336,6 +336,19 @@ Update procedure See the example in the AsyncStage migration section for an example of this procedure. +StatefulStage has been replaced by GraphStage +============================================= + +The :class:`StatefulStage` class had some flaws and limitations, most notably around completion handling which +caused subtle bugs. The new :class:`GraphStage` (:ref:`graphstage-java`) solves these issues and should be used +instead. + +Update procedure +---------------- + +There is no mechanical update procedure available. Please consult the :class:`GraphStage` documentation +(:ref:`graphstage-java`). + AsyncStage has been replaced by GraphStage ========================================== diff --git a/akka-docs-dev/rst/java/stream-customize.rst b/akka-docs-dev/rst/java/stream-customize.rst index 4019a10af6..0e0f8068a7 100644 --- a/akka-docs-dev/rst/java/stream-customize.rst +++ b/akka-docs-dev/rst/java/stream-customize.rst @@ -9,6 +9,210 @@ is sometimes necessary to define new transformation stages either because some f stock operations, or for performance reasons. In this part we show how to build custom processing stages and graph junctions of various kinds. +.. _graphstage-java: + +Custom processing with GraphStage +================================= + +The :class:`GraphStage` abstraction can be used to create arbitrary graph processing stages with any number of input +or output ports. It is a counterpart of the ``FlowGraph.create()`` method which creates new stream processing +stages by composing others. Where :class:`GraphStage` differs is that it creates a stage that is itself not divisible into +smaller ones, and allows state to be maintained inside it in a safe way. + +As a first motivating example, we will build a new :class:`Source` that will simply emit numbers from 1 until it is +cancelled. To start, we need to define the "interface" of our stage, which is called *shape* in Akka Streams terminology +(this is explained in more detail in the section :ref:`composition-java`). + +.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/GraphStageDocTest.java#simple-source + +As you see, in itself the :class:`GraphStage` only defines the ports of this stage and a shape that contains the ports. +It also has a user implemented method called ``createLogic``. If you recall, stages are reusable in multiple +materializations, each resulting in a different executing entity. In the case of :class:`GraphStage` the actual running +logic is modeled as an instance of a :class:`GraphStageLogic` which will be created by the materializer by calling +the ``createLogic`` method. + +In order to emit from a :class:`Source` in a backpressured stream one needs first to have demand from downstream. +To receive the necessary events one needs to register a subclass of :class:`AbstractOutHandler` with the output port +(:class:`Outlet`). This handler will receive events related to the lifecycle of the port. In our case we need to +override ``onPull()`` which indicates that we are free to emit a single element. There is another callback, +``onDownstreamFinish()`` which is called if the downstream cancelled. Since the default behavior of that callback is +to stop the stage, we don't need to override it. In the ``onPull`` callback we simply emit the next number. + +Instances of the above :class:`GraphStage` are subclasses of ``Graph,Unit>`` which means +that they are already usable in many situations, but do not provide the DSL methods we usually have for other +:class:`Source` s. In order to convert this :class:`Graph` to a proper :class:`Source` we need to wrap it using +``Source.fromGraph`` (see :ref:`composition-java` for more details about graphs and DSLs). Now we can use the +source as any other built-in one: + +.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/GraphStageDocTest.java#simple-source-usage + +Port states, AbstractInHandler and AbstractOutHandler +----------------------------------------------------- + +In order to interact with a port (:class:`Inlet` or :class:`Outlet`) of the stage we need to be able to receive events +and generate new events belonging to the port. From the :class:`GraphStageLogic` the following operations are available +on an output port: + +* ``push(out,elem)`` pushes an element to the output port. Only possible after the port has been pulled by downstream. +* ``complete(out)`` closes the output port normally. +* ``fail(out,exception)`` closes the port with a failure signal. + + +The events corresponding to an *output* port can be received in an :class:`AbstractOutHandler` instance registered to the +output port using ``setHandler(out,handler)``. This handler has two callbacks: + +* ``onPull()`` is called when the output port is ready to emit the next element, ``push(out, elem)`` is now allowed + to be called on this port. +* ``onDownstreamFinish()`` is called once the downstream has cancelled and no longer allows messages to be pushed to it. + No more ``onPull()`` will arrive after this event. If not overridden this will default to stopping the stage. + +Also, there are two query methods available for output ports: + +* ``isAvailable(out)`` returns true if the port can be pushed. +* ``isClosed(out)`` returns true if the port is closed. At this point the port can not be pushed and will not be pulled anymore. + +The relationship of the above operations, events and queries are summarized in the state machine below. Green shows +the initial state while orange indicates the end state. If an operation is not listed for a state, then it is invalid +to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen +in that state. + +| + +.. image:: ../images/outport_transitions.png +:align: center + +| + +The following operations are available for *input* ports: + +* ``pull(in)`` requests a new element from an input port. This is only possible after the port has been pushed by upstream. +* ``grab(in)`` acquires the element that has been received during an ``onPush()``. It cannot be called again until the + port is pushed again by the upstream. +* ``cancel(in)`` closes the input port. + +The events corresponding to an *input* port can be received in an :class:`AbstractInHandler` instance registered to the +input port using ``setHandler(in, handler)``. This handler has three callbacks: + +* ``onPush()`` is called when the output port has now a new element. Now it is possible to aquire this element using + ``grab()`` and/or call ``pull(in)`` on the port to request the next element. It is not mandatory to grab the + element, but if it is pulled while the element has not been grabbed it will drop the buffered element. +* ``onUpstreamFinish()`` is called once the upstream has completed and no longer can be pulled for new elements. + No more ``onPush()`` will arrive after this event. If not overridden this will default to stopping the stage. +* ``onUpstreamFailure()`` is called if the upstream failed with an exception and no longer can be pulled for new elements. + No more ``onPush()`` will arrive after this event. If not overridden this will default to failing the stage. + +Also, there are three query methods available for input ports: + +* ``isAvailable(out)`` returns true if a data element can be grabbed from the port +* ``hasBeenPulled(out)`` returns true if the port has been already pulled. Calling ``pull(in)`` in this state is illegal. +* ``isClosed(in)`` returns true if the port is closed. At this point the port can not be pulled and will not be pushed anymore. + +The relationship of the above operations, events and queries are summarized in the state machine below. Green shows +the initial state while orange indicates the end state. If an operation is not listed for a state, then it is invalid +to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen +in that state. + +| + +.. image:: ../images/inport_transitions.png +:align: center + +| + +Finally, there are two methods available for convenience to complete the stage and all of its ports: + +* ``completeStage()`` is equivalent to closing all output ports and cancelling all input ports. +* ``failStage(exception)`` is equivalent to failing all output ports and cancelling all input ports. + + +Completion +---------- + +**This section is a stub and will be extended in the next release** + +Stages by default automatically stop once all of their ports (input and output) have been closed externally or internally. +It is possible to opt out from this behavior by overriding ``keepGoingAfterAllPortsClosed`` and returning true in +the :class:`GraphStageLogic` implementation. In this case the stage **must** be explicitly closed by calling ``completeStage()`` +or ``failStage(exception)``. This feature carries the risk of leaking streams and actors, therefore it should be used +with care. + +Using timers +------------ + +**This section is a stub and will be extended in the next release** + +It is possible to use timers in :class:`GraphStages` by using :class:`TimerGraphStageLogic` as the base class for +the returned logic. Timers can be scheduled by calling one of ``scheduleOnce(key,delay)``, ``schedulePeriodically(key,period)`` or +``schedulePeriodicallyWithInitialDelay(key,delay,period)`` and passing an object as a key for that timer (can be any object, for example +a :class:`String`). The ``onTimer(key)`` method needs to be overridden and it will be called once the timer of ``key`` +fires. It is possible to cancel a timer using ``cancelTimer(key)`` and check the status of a timer with +``isTimerActive(key)``. Timers will be automatically cleaned up when the stage completes. + +Timers can not be scheduled from the constructor of the logic, but it is possible to schedule them from the +``preStart()`` lifecycle hook. + +Using asynchronous side-channels +-------------------------------- + +**This section is a stub and will be extended in the next release** + +In order to receive asynchronous events that are not arriving as stream elements (for example a completion of a future +or a callback from a 3rd party API) one must acquire a :class:`AsyncCallback` by calling ``getAsyncCallback()`` from the +stage logic. The method ``getAsyncCallback`` takes as a parameter a callback that will be called once the asynchronous +event fires. It is important to **not call the callback directly**, instead, the external API must call the +``invoke(event)`` method on the returned :class:`AsyncCallback`. The execution engine will take care of calling the +provided callback in a thread-safe way. The callback can safely access the state of the :class:`GraphStageLogic` +implementation. + +Sharing the AsyncCallback from the constructor risks race conditions, therefore it is recommended to use the +``preStart()`` lifecycle hook instead. + +Integration with actors +----------------------- + +**This section is a stub and will be extended in the next release** +**This is an experimental feature*** + +It is possible to acquire an ActorRef that can be addressed from the outside of the stage, similarly how +:class:`AsyncCallback` allows injecting asynchronous events into a stage logic. This reference can be obtained +by calling ``getStageActorRef(receive)`` passing in a function that takes a :class:`Pair` of the sender +:class:`ActorRef` and the received message. This reference can be used to watch other actors by calling its ``watch(ref)`` +or ``unwatch(ref)`` methods. The reference can be also watched by external actors. The current limitations of this +:class:`ActorRef` are: + + - they are not location transparent, they cannot be accessed via remoting. + - they cannot be returned as materialized values. + - they cannot be accessed from the constructor of the :class:`GraphStageLogic`, but they can be accessed from the + ``preStart()`` method. + +Custom materialized values +-------------------------- + +**This section is a stub and will be extended in the next release** + +Custom stages can return materialized values instead of ``Unit`` by inheriting from :class:`GraphStageWithMaterializedValue` +instead of the simpler :class:`GraphStage`. The difference is that in this case the method +``createLogicAndMaterializedValue(inheritedAttributes)`` needs to be overridden, overridden, and in addition to the +stage logic the materialized value must be provided + +.. warning:: + There is no built-in synchronization of accessing this value from both of the thread where the logic runs and + the thread that got hold of the materialized value. It is the responsibility of the programmer to add the + necessary (non-blocking) synchronization and visibility guarantees to this shared object. + +Using attributes to affect the behavior of a stage +-------------------------------------------------- + +**This section is a stub and will be extended in the next release** + +Stages can access the :class:`Attributes` object created by the materializer. This contains all the applied (inherited) +attributes applying to the stage, ordered from least specific (outermost) towards the most specific (innermost) +attribute. It is the responsibility of the stage to decide how to reconcile this inheritance chain to a final effective +decision. + +See :ref:`composition-java` for an explanation on how attributes work. + + Custom linear processing stages =============================== @@ -188,19 +392,6 @@ only calls ``ctx.pull()`` and allow the environment do process elements faster t extending ``PushStage`` the environment can be sure that ``onPull()`` was not overridden since it is ``final`` on ``PushStage``. - -Using StatefulStage -------------------- - -On top of ``PushPullStage`` which is the most elementary and low-level abstraction and ``PushStage`` that is a -convenience class that also informs the environment about possible optimizations ``StatefulStage`` is a new tool that -builds on ``PushPullStage`` directly, adding various convenience methods on top of it. It is possible to explicitly -maintain state-machine like states using its ``become()`` method to encapsulates states explicitly. There is also -a handy ``emit()`` method that simplifies emitting multiple values given as an iterator. To demonstrate this feature -we reimplemented ``Duplicator`` in terms of a ``StatefulStage``: - -.. includecode:: ../../../akka-samples/akka-docs-java-lambda/src/test/java/docs/stream/FlowStagesDocTest.java#doubler-stateful - Using DetachedStage ------------------- @@ -254,13 +445,6 @@ The following code example demonstrates the buffer class corresponding to the me the downstream is held, so the framework invokes onPull() to avoid this situation. This is similar to the termination logic already shown for :class:`PushPullStage`. -Custom graph processing junctions -================================= - -To extend available fan-in and fan-out structures (graph stages) Akka Streams include :class:`GraphStage`. This is an -advanced usage DSL that should only be needed in rare and special cases, documentation will be forthcoming in one of the -next releases. - Thread safety of custom processing stages ========================================= diff --git a/akka-docs-dev/rst/scala/code/docs/stream/GraphStageDocSpec.scala b/akka-docs-dev/rst/scala/code/docs/stream/GraphStageDocSpec.scala new file mode 100644 index 0000000000..06abf7e2ec --- /dev/null +++ b/akka-docs-dev/rst/scala/code/docs/stream/GraphStageDocSpec.scala @@ -0,0 +1,86 @@ +/** + * Copyright (C) 2015 Typesafe Inc. + */ +package docs.stream + +import akka.stream.javadsl.Sink +import akka.stream.scaladsl.Source +import akka.stream.stage.{ OutHandler, GraphStage, GraphStageLogic } +import akka.stream._ + +import akka.stream.testkit.AkkaSpec + +import scala.concurrent.{ Await, Future } +import scala.concurrent.duration._ + +class GraphStageDocSpec extends AkkaSpec { + + implicit val mat = ActorMaterializer() + + "Demonstrate creation of GraphStage boilerplate" in { + //#boilerplate-example + import akka.stream.SourceShape + import akka.stream.stage.GraphStage + + class NumbersSource extends GraphStage[SourceShape[Int]] { + // Define the (sole) output port of this stage + val out: Outlet[Int] = Outlet("NumbersSource") + // Define the shape of this stage, which is SourceShape with the port we defined above + override val shape: SourceShape[Int] = SourceShape(out) + + // This is where the actual (possibly stateful) logic will live + override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = ??? + } + //#boilerplate-example + + } + + "Demonstrate creation of GraphStage Source" in { + //#custom-source-example + import akka.stream.SourceShape + import akka.stream.Graph + import akka.stream.stage.GraphStage + import akka.stream.stage.OutHandler + + class NumbersSource extends GraphStage[SourceShape[Int]] { + val out: Outlet[Int] = Outlet("NumbersSource") + override val shape: SourceShape[Int] = SourceShape(out) + + override def createLogic(inheritedAttributes: Attributes): GraphStageLogic = + new GraphStageLogic(shape) { + // All state MUST be inside the GraphStageLogic, + // never inside the enclosing GraphStage. + // This state is safe to access and modify from all the + // callbacks that are provided by GraphStageLogic and the + // registered handlers. + private var counter = 1 + + setHandler(out, new OutHandler { + override def onPull(): Unit = { + push(out, counter) + counter += 1 + } + }) + } + } + //#custom-source-example + + //#simple-source-usage + // A GraphStage is a proper Graph, just like what FlowGraph.create would return + val sourceGraph: Graph[SourceShape[Int], Unit] = new NumbersSource + + // Create a Source from the Graph to access the DSL + val mySource: Source[Int, Unit] = Source.fromGraph(new NumbersSource) + + // Returns 55 + val result1: Future[Int] = mySource.take(10).runFold(0)(_ + _) + + // The source is reusable. This returns 5050 + val result2: Future[Int] = mySource.take(100).runFold(0)(_ + _) + //#simple-source-usage + + Await.result(result1, 3.seconds) should ===(55) + Await.result(result2, 3.seconds) should ===(5050) + } + +} diff --git a/akka-docs-dev/rst/scala/migration-guide-1.0-2.x-scala.rst b/akka-docs-dev/rst/scala/migration-guide-1.0-2.x-scala.rst index 40ac6c43e5..acde374a9b 100644 --- a/akka-docs-dev/rst/scala/migration-guide-1.0-2.x-scala.rst +++ b/akka-docs-dev/rst/scala/migration-guide-1.0-2.x-scala.rst @@ -325,6 +325,20 @@ Update procedure See the example in the AsyncStage migration section for an example of this procedure. +StatefulStage has been replaced by GraphStage +============================================= + +The :class:`StatefulStage` class had some flaws and limitations, most notably around completion handling which +caused subtle bugs. The new :class:`GraphStage` (:ref:`graphstage-java`) solves these issues and should be used +instead. + +Update procedure +---------------- + +There is no mechanical update procedure available. Please consult the :class:`GraphStage` documentation +(:ref:`graphstage-java`). + + AsyncStage has been replaced by GraphStage ========================================== diff --git a/akka-docs-dev/rst/scala/stream-customize.rst b/akka-docs-dev/rst/scala/stream-customize.rst index 7d3133dad6..1b175755d0 100644 --- a/akka-docs-dev/rst/scala/stream-customize.rst +++ b/akka-docs-dev/rst/scala/stream-customize.rst @@ -9,8 +9,216 @@ is sometimes necessary to define new transformation stages either because some f stock operations, or for performance reasons. In this part we show how to build custom processing stages and graph junctions of various kinds. -Custom linear processing stages -=============================== +.. _graphstage-scala: + +Custom processing with GraphStage +================================= + +The :class:`GraphStage` abstraction can be used to create arbitrary graph processing stages with any number of input +or output ports. It is a counterpart of the ``FlowGraph.create()`` method which creates new stream processing +stages by composing others. Where :class:`GraphStage` differs is that it creates a stage that is itself not divisible into +smaller ones, and allows state to be maintained inside it in a safe way. + +As a first motivating example, we will build a new :class:`Source` that will simply emit numbers from 1 until it is +cancelled. To start, we need to define the "interface" of our stage, which is called *shape* in Akka Streams terminology +(this is explained in more detail in the section :ref:`composition-scala`). This is how this looks like: + +.. includecode:: code/docs/stream/GraphStageDocSpec.scala#boilerplate-example + +As you see, in itself the :class:`GraphStage` only defines the ports of this stage and a shape that contains the ports. +It also has, a currently unimplemented method called ``createLogic``. If you recall, stages are reusable in multiple +materializations, each resulting in a different executing entity. In the case of :class:`GraphStage` the actual running +logic is modeled as an instance of a :class:`GraphStageLogic` which will be created by the materializer by calling +the ``createLogic`` method. In other words, all we need to do is to create a suitable logic that will emit the +numbers we want. + +In order to emit from a :class:`Source` in a backpressured stream one needs first to have demand from downstream. +To receive the necessary events one needs to register a subclass of :class:`OutHandler` with the output port +(:class:`Outlet`). This handler will receive events related to the lifecycle of the port. In our case we need to +override ``onPull()`` which indicates that we are free to emit a single element. There is another callback, +``onDownstreamFinish()`` which is called if the downstream cancelled. Since the default behavior of that callback is +to stop the stage, we don't need to override it. In the ``onPull`` callback we will simply emit the next number. This +is how it looks like in the end: + +.. includecode:: code/docs/stream/GraphStageDocSpec.scala#custom-source-example + +Instances of the above :class:`GraphStage` are subclasses of ``Graph[SourceShape[Int],Unit]`` which means +that they are already usable in many situations, but do not provide the DSL methods we usually have for other +:class:`Source` s. In order to convert this :class:`Graph` to a proper :class:`Source` we need to wrap it using +``Source.fromGraph`` (see :ref:`composition-scala` for more details about graphs and DSLs). Now we can use the +source as any other built-in one: + +.. includecode:: code/docs/stream/GraphStageDocSpec.scala#simple-source-usage + +Port states, InHandler and OutHandler +------------------------------------- + +In order to interact with a port (:class:`Inlet` or :class:`Outlet`) of the stage we need to be able to receive events +and generate new events belonging to the port. From the :class:`GraphStageLogic` the following operations are available +on an output port: + +* ``push(out,elem)`` pushes an element to the output port. Only possible after the port has been pulled by downstream. +* ``complete(out)`` closes the output port normally. +* ``fail(out,exception)`` closes the port with a failure signal. + + +The events corresponding to an *output* port can be received in an :class:`OutHandler` instance registered to the +output port using ``setHandler(out,handler)``. This handler has two callbacks: + +* ``onPull()`` is called when the output port is ready to emit the next element, ``push(out, elem)`` is now allowed + to be called on this port. +* ``onDownstreamFinish()`` is called once the downstream has cancelled and no longer allows messages to be pushed to it. + No more ``onPull()`` will arrive after this event. If not overridden this will default to stopping the stage. + +Also, there are two query methods available for output ports: + +* ``isAvailable(out)`` returns true if a data element can be grabbed from the port +* ``isClosed(out)`` returns true if the port is closed. At this point the port can not be pushed and will not be pulled anymore. + +The relationship of the above operations, events and queries are summarized in the state machine below. Green shows +the initial state while orange indicates the end state. If an operation is not listed for a state, then it is invalid +to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen +in that state. + +| + +.. image:: ../images/outport_transitions.png + :align: center + +| + +The following operations are available for *input* ports: + +* ``pull(in)`` requests a new element from an input port. This is only possible after the port has been pushed by upstream. +* ``grab(in)`` acquires the element that has been received during an ``onPush()``. It cannot be called again until the + port is pushed again by the upstream. +* ``cancel(in)`` closes the input port. + +The events corresponding to an *input* port can be received in an :class:`InHandler` instance registered to the +input port using ``setHandler(in, handler)``. This handler has three callbacks: + +* ``onPush()`` is called when the output port has now a new element. Now it is possible to aquire this element using + ``grab()`` and/or call ``pull(in)`` on the port to request the next element. It is not mandatory to grab the + element, but if it is pulled while the element has not been grabbed it will drop the buffered element. +* ``onUpstreamFinish()`` is called once the upstream has completed and no longer can be pulled for new elements. + No more ``onPush()`` will arrive after this event. If not overridden this will default to stopping the stage. +* ``onUpstreamFailure()`` is called if the upstream failed with an exception and no longer can be pulled for new elements. + No more ``onPush()`` will arrive after this event. If not overridden this will default to failing the stage. + +Also, there are three query methods available for input ports: + +* ``isAvailable(out)`` returns true if the port can be grabbed. +* ``hasBeenPulled(out)`` returns true if the port has been already pulled. Calling ``pull(in)`` in this state is illegal. +* ``isClosed(in)`` returns true if the port is closed. At this point the port can not be pulled and will not be pushed anymore. + +The relationship of the above operations, events and queries are summarized in the state machine below. Green shows +the initial state while orange indicates the end state. If an operation is not listed for a state, then it is invalid +to call it while the port is in that state. If an event is not listed for a state, then that event cannot happen +in that state. + +| + +.. image:: ../images/inport_transitions.png + :align: center + +| + +Finally, there are two methods available for convenience to complete the stage and all of its ports: + +* ``completeStage()`` is equivalent to closing all output ports and cancelling all input ports. +* ``failStage(exception)`` is equivalent to failing all output ports and cancelling all input ports. + + +Completion +---------- + +**This section is a stub and will be extended in the next release** + +Stages by default automatically stop once all of their ports (input and output) have been closed externally or internally. +It is possible to opt out from this behavior by overriding ``keepGoingAfterAllPortsClosed`` and returning true in +the :class:`GraphStageLogic` implementation. In this case the stage **must** be explicitly closed by calling ``completeStage()`` +or ``failStage(exception)``. This feature carries the risk of leaking streams and actors, therefore it should be used +with care. + +Using timers +------------ + +**This section is a stub and will be extended in the next release** + +It is possible to use timers in :class:`GraphStages` by using :class:`TimerGraphStageLogic` as the base class for +the returned logic. Timers can be scheduled by calling one of ``scheduleOnce(key,delay)``, ``schedulePeriodically(key,period)`` or +``schedulePeriodicallyWithInitialDelay(key,delay,period)`` and passing an object as a key for that timer (can be any object, for example +a :class:`String`). The ``onTimer(key)`` method needs to be overridden and it will be called once the timer of ``key`` +fires. It is possible to cancel a timer using ``cancelTimer(key)`` and check the status of a timer with +``isTimerActive(key)``. Timers will be automatically cleaned up when the stage completes. + +Timers can not be scheduled from the constructor of the logic, but it is possible to schedule them from the +``preStart()`` lifecycle hook. + +Using asynchronous side-channels +-------------------------------- + +**This section is a stub and will be extended in the next release** + +In order to receive asynchronous events that are not arriving as stream elements (for example a completion of a future +or a callback from a 3rd party API) one must acquire a :class:`AsyncCallback` by calling ``getAsyncCallback()`` from the +stage logic. The method ``getAsyncCallback`` takes as a parameter a callback that will be called once the asynchronous +event fires. It is important to **not call the callback directly**, instead, the external API must call the +``invoke(event)`` method on the returned :class:`AsyncCallback`. The execution engine will take care of calling the +provided callback in a thread-safe way. The callback can safely access the state of the :class:`GraphStageLogic` +implementation. + +Sharing the AsyncCallback from the constructor risks race conditions, therefore it is recommended to use the +``preStart()`` lifecycle hook instead. + +Integration with actors +----------------------- + +**This section is a stub and will be extended in the next release** +**This is an experimental feature*** + +It is possible to acquire an ActorRef that can be addressed from the outside of the stage, similarly how +:class:`AsyncCallback` allows injecting asynchronous events into a stage logic. This reference can be obtained +by calling ``getStageActorRef(receive)`` passing in a function that takes a :class:`Pair` of the sender +:class:`ActorRef` and the received message. This reference can be used to watch other actors by calling its ``watch(ref)`` +or ``unwatch(ref)`` methods. The reference can be also watched by external actors. The current limitations of this +:class:`ActorRef` are: + + - they are not location transparent, they cannot be accessed via remoting. + - they cannot be returned as materialized values. + - they cannot be accessed from the constructor of the :class:`GraphStageLogic`, but they can be accessed from the + ``preStart()`` method. + +Custom materialized values +-------------------------- + +**This section is a stub and will be extended in the next release** + +Custom stages can return materialized values instead of ``Unit`` by inheriting from :class:`GraphStageWithMaterializedValue` +instead of the simpler :class:`GraphStage`. The difference is that in this case the method +``createLogicAndMaterializedValue(inheritedAttributes)`` needs to be overridden, overridden, and in addition to the +stage logic the materialized value must be provided + +.. warning:: + There is no built-in synchronization of accessing this value from both of the thread where the logic runs and + the thread that got hold of the materialized value. It is the responsibility of the programmer to add the + necessary (non-blocking) synchronization and visibility guarantees to this shared object. + +Using attributes to affect the behavior of a stage +-------------------------------------------------- + +**This section is a stub and will be extended in the next release** + +Stages can access the :class:`Attributes` object created by the materializer. This contains all the applied (inherited) +attributes applying to the stage, ordered from least specific (outermost) towards the most specific (innermost) +attribute. It is the responsibility of the stage to decide how to reconcile this inheritance chain to a final effective +decision. + +See :ref:`composition-scala` for an explanation on how attributes work. + + +Custom linear processing stages with PushPullStage +================================================== To extend the available transformations on a :class:`Flow` or :class:`Source` one can use the ``transform()`` method which takes a factory function returning a :class:`Stage`. Stages come in different flavors swhich we will introduce in this @@ -190,18 +398,6 @@ extending ``PushStage`` the environment can be sure that ``onPull()`` was not ov ``PushStage``. -Using StatefulStage -------------------- - -On top of ``PushPullStage`` which is the most elementary and low-level abstraction and ``PushStage`` that is a -convenience class that also informs the environment about possible optimizations ``StatefulStage`` is a new tool that -builds on ``PushPullStage`` directly, adding various convenience methods on top of it. It is possible to explicitly -maintain state-machine like states using its ``become()`` method to encapsulates states explicitly. There is also -a handy ``emit()`` method that simplifies emitting multiple values given as an iterator. To demonstrate this feature -we reimplemented ``Duplicator`` in terms of a ``StatefulStage``: - -.. includecode:: code/docs/stream/FlowStagesSpec.scala#doubler-stateful - Using DetachedStage ------------------- @@ -255,12 +451,6 @@ The following code example demonstrates the buffer class corresponding to the me the downstream is held, so the framework invokes onPull() to avoid this situation. This is similar to the termination logic already shown for :class:`PushPullStage`. -Custom graph processing junctions -================================= - -To extend available fan-in and fan-out structures (graph stages) Akka Streams include :class:`GraphStage`. This is an -advanced usage DSL that should only be needed in rare and special cases, documentation will be forthcoming in one of the -next releases. Thread safety of custom processing stages ========================================= diff --git a/akka-docs-dev/rst/scala/stream-testkit.rst b/akka-docs-dev/rst/scala/stream-testkit.rst index 0f642455b6..c249929642 100644 --- a/akka-docs-dev/rst/scala/stream-testkit.rst +++ b/akka-docs-dev/rst/scala/stream-testkit.rst @@ -68,3 +68,22 @@ You can also inject exceptions and test sink behaviour on error conditions. Test source and sink can be used together in combination when testing flows. .. includecode:: code/docs/stream/StreamTestKitDocSpec.scala#test-source-and-sink + + +Fuzzing Mode +============ + +For testing, it is possible to enable a special stream execution mode that exercises concurrent execution paths +more aggressively (at the cost of reduced performance) and therefore helps exposing race conditions in tests. To +enable this setting add the following line to your configuration: + +:: + + akka.stream.materializer.debug.fuzzing-mode = on + + +.. warning:: + + Never use this setting in production or benchmarks. This is a testing tool to provide more coverage of your code + during tests, but it reduces the throughput of streams. A warning message will be logged if you have this setting + enabled. \ No newline at end of file diff --git a/akka-stream/src/main/scala/akka/stream/javadsl/Flow.scala b/akka-stream/src/main/scala/akka/stream/javadsl/Flow.scala index dc50ff427a..34221bdd90 100644 --- a/akka-stream/src/main/scala/akka/stream/javadsl/Flow.scala +++ b/akka-stream/src/main/scala/akka/stream/javadsl/Flow.scala @@ -799,7 +799,7 @@ final class Flow[-In, +Out, +Mat](delegate: scaladsl.Flow[In, Out, Mat]) extends * '''Completes when''' upstream completes * * '''Cancels when''' downstream cancels and substreams cancel - * + * * See also [[Flow.splitAfter]]. */ def splitWhen(p: function.Predicate[Out]): javadsl.Flow[In, Source[Out, Unit], Mat] = diff --git a/akka-stream/src/main/scala/akka/stream/stage/Stage.scala b/akka-stream/src/main/scala/akka/stream/stage/Stage.scala index 5a3cc187c7..c2c7a49da5 100644 --- a/akka-stream/src/main/scala/akka/stream/stage/Stage.scala +++ b/akka-stream/src/main/scala/akka/stream/stage/Stage.scala @@ -411,6 +411,7 @@ private[akka] object StatefulStage { * * Use [[#terminationEmit]] to push final elements from [[#onUpstreamFinish]] or [[#onUpstreamFailure]]. */ +@deprecated("StatefulStage is deprecated, please use GraphStage instead.", "2.0-M2") abstract class StatefulStage[In, Out] extends PushPullStage[In, Out] { import StatefulStage._