Merge pull request #19578 from akka/wip-19440-completionStage-RK

#19440 replace Scala Future usage with CompletionStage in javadsl
This commit is contained in:
Roland Kuhn 2016-01-24 22:14:18 +01:00
commit 6ba20ac673
118 changed files with 1646 additions and 1379 deletions

View file

@ -7,6 +7,25 @@ Migration Guide 2.0.x to 2.4.x
General notes
=============
Java DSL now uses Java 8 types: CompletionStage and Optional
------------------------------------------------------------
In order to provide a top-notch Java API we switched from Scalas Future and Akkas
``akka.japi.Option`` interim solutions to the JDKs own types for deferred computation
and optional results. This has been done throughout Streams & HTTP, most notably changing most
materialized types, but also the signature of the ``mapAsync`` combinator and the
asynchronous route result combinators in the HTTP DSL.
The ``akka.pattern`` package has been updated with a new set of implementations within
the ``PatternCS`` class that provide the ability to interact between Actors and Futures
(or streams) for ``CompletionStage``.
Should you have the need to use Scala Futures with these new Java APIs please use
the ``scala-java8-compat`` library that comes as a dependency of Akka. For more
information see `the documentation``_.
.. _`the documentation`:: https://github.com/scala/scala-java8-compat
akka.Done and akka.NotUsed replacing Unit and BoxedUnit
-------------------------------------------------------

View file

@ -253,7 +253,7 @@ type is of the nested module (indicated by the color *red* on the diagram):
.. includecode:: ../code/docs/stream/CompositionDocTest.java#mat-combine-1
Next, we create a composite :class:`Flow` from two smaller components. Here, the second enclosed :class:`Flow` has a
materialized type of :class:`Future<OutgoingConnection>`, and we propagate this to the parent by using ``Keep.right()``
materialized type of :class:`CompletionStage<OutgoingConnection>`, and we propagate this to the parent by using ``Keep.right()``
as the combiner function (indicated by the color *yellow* on the diagram):
.. includecode:: ../code/docs/stream/CompositionDocTest.java#mat-combine-2
@ -267,7 +267,7 @@ we use ``Keep.both()`` to get a :class:`Pair` of them as the materialized type o
As the last example, we wire together ``nestedSource`` and ``nestedSink`` and we use a custom combiner function to
create a yet another materialized type of the resulting :class:`RunnableGraph`. This combiner function just ignores
the :class:`Future<Sink>` part, and wraps the other two values in a custom case class :class:`MyClass`
the :class:`CompletionStage<Sink>` part, and wraps the other two values in a custom case class :class:`MyClass`
(indicated by color *purple* on the diagram):
.. includecode:: ../code/docs/stream/CompositionDocTest.java#mat-combine-4a

View file

@ -60,7 +60,7 @@ In this recipe we will use the ``grouped`` stream operation that groups incoming
size collections (it can be seen as the almost opposite version of the "Flattening a stream of sequences" recipe
we showed before). By using a ``grouped(MAX_ALLOWED_SIZE)`` we create a stream of groups
with maximum size of ``MaxAllowedSeqSize`` and then we take the first element of this stream by attaching a ``Sink.head()``. What we get is a
:class:`Future` containing a sequence with all the elements of the original up to ``MAX_ALLOWED_SIZE`` size (further
:class:`CompletionStage` containing a sequence with all the elements of the original up to ``MAX_ALLOWED_SIZE`` size (further
elements are dropped).
.. includecode:: ../code/docs/stream/javadsl/cookbook/RecipeToStrict.java#draining-to-list

View file

@ -67,7 +67,7 @@ Assume that we can lookup their email address using:
.. includecode:: ../code/docs/stream/IntegrationDocTest.java#email-address-lookup2
The ``Future`` is completed with ``Failure`` if the email is not found.
The ``CompletionStage`` is completed normally if the email is not found.
Transforming the stream of authors to a stream of email addresses by using the ``lookupEmail``
service can be done with ``mapAsync`` and we use ``Supervision.getResumingDecider`` to drop
@ -76,4 +76,4 @@ unknown email addresses:
.. includecode:: ../code/docs/stream/IntegrationDocTest.java#email-addresses-mapAsync-supervision
If we would not use ``Resume`` the default stopping strategy would complete the stream
with failure on the first ``Future`` that was completed with ``Failure``.
with failure on the first ``CompletionStage`` that was completed exceptionally.

View file

@ -80,7 +80,7 @@ one actor prepare the work, and then have it be materialized at some completely
After running (materializing) the ``RunnableGraph`` we get a special container object, the ``MaterializedMap``. Both
sources and sinks are able to put specific objects into this map. Whether they put something in or not is implementation
dependent. For example a ``FoldSink`` will make a ``Future`` available in this map which will represent the result
dependent. For example a ``FoldSink`` will make a ``CompletionStage`` available in this map which will represent the result
of the folding process over the stream. In general, a stream can expose multiple materialized values,
but it is quite common to be interested in only the value of the Source or the Sink in the stream. For this reason
there is a convenience method called ``runWith()`` available for ``Sink``, ``Source`` or ``Flow`` requiring, respectively,
@ -105,7 +105,7 @@ of the given sink or source.
Since a stream can be materialized multiple times, the ``MaterializedMap`` returned is different for each materialization.
In the example below we create two running materialized instance of the stream that we described in the ``runnable``
variable, and both materializations give us a different ``Future`` from the map even though we used the same ``sink``
variable, and both materializations give us a different ``CompletionStage`` from the map even though we used the same ``sink``
to refer to the future:
.. includecode:: ../code/docs/stream/FlowDocTest.java#stream-reuse

View file

@ -222,7 +222,7 @@ times to acquire the necessary number of outlets.
.. includecode:: ../code/docs/stream/FlowGraphDocTest.java#flow-graph-matvalue
Be careful not to introduce a cycle where the materialized value actually contributes to the materialized value.
The following example demonstrates a case where the materialized ``Future`` of a fold is fed back to the fold itself.
The following example demonstrates a case where the materialized ``CompletionStage`` of a fold is fed back to the fold itself.
.. includecode:: ../code/docs/stream/FlowGraphDocTest.java#flow-graph-matvalue-cycle

View file

@ -169,7 +169,7 @@ Finally, sending the emails:
.. includecode:: ../code/docs/stream/IntegrationDocTest.java#send-emails
``mapAsync`` is applying the given function that is calling out to the external service to
each of the elements as they pass through this processing step. The function returns a :class:`Future`
each of the elements as they pass through this processing step. The function returns a :class:`CompletionStage`
and the value of that future will be emitted downstreams. The number of Futures
that shall run in parallel is given as the first argument to ``mapAsync``.
These Futures may complete in any order, but the elements that are emitted
@ -190,8 +190,8 @@ is not important and then we can use the more efficient ``mapAsyncUnordered``:
.. includecode:: ../code/docs/stream/IntegrationDocTest.java#external-service-mapAsyncUnordered
In the above example the services conveniently returned a :class:`Future` of the result.
If that is not the case you need to wrap the call in a :class:`Future`. If the service call
In the above example the services conveniently returned a :class:`CompletionStage` of the result.
If that is not the case you need to wrap the call in a :class:`CompletionStage`. If the service call
involves blocking you must also make sure that you run it on a dedicated execution context, to
avoid starvation and disturbance of other tasks in the system.
@ -215,7 +215,7 @@ external service, you can use ``ask``:
.. includecode:: ../code/docs/stream/IntegrationDocTest.java#save-tweets
Note that if the ``ask`` is not completed within the given timeout the stream is completed with failure.
If that is not desired outcome you can use ``recover`` on the ``ask`` :class:`Future`.
If that is not desired outcome you can use ``recover`` on the ``ask`` :class:`CompletionStage`.
Illustrating ordering and parallelism
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View file

@ -16,7 +16,7 @@ Streaming TCP
Accepting connections: Echo Server
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In order to implement a simple EchoServer we ``bind`` to a given address, which returns a ``Source<IncomingConnection, Future<ServerBinding>>``,
In order to implement a simple EchoServer we ``bind`` to a given address, which returns a ``Source<IncomingConnection, CompletionStage<ServerBinding>>``,
which will emit an :class:`IncomingConnection` element for each new connection that the Server should handle:
.. includecode:: ../code/docs/stream/io/StreamTcpDocTest.java#echo-server-simple-bind

View file

@ -163,21 +163,21 @@ First, let's write such an element counter using ``Flow.of(Class)`` and ``Sink.f
First we prepare a reusable ``Flow`` that will change each incoming tweet into an integer of value ``1``. We'll use this in
order to combine those with a ``Sink.fold`` that will sum all ``Integer`` elements of the stream and make its result available as
a ``Future<Integer>``. Next we connect the ``tweets`` stream to ``count`` with ``via``. Finally we connect the Flow to the previously
a ``CompletionStage<Integer>``. Next we connect the ``tweets`` stream to ``count`` with ``via``. Finally we connect the Flow to the previously
prepared Sink using ``toMat``.
Remember those mysterious ``Mat`` type parameters on ``Source<Out, Mat>``, ``Flow<In, Out, Mat>`` and ``Sink<In, Mat>``?
They represent the type of values these processing parts return when 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.
The materialized type of ``sumSink`` is ``Future<Integer>`` and because of using ``Keep.right``, the resulting :class:`RunnableGraph`
has also a type parameter of ``Future<Integer>``.
The materialized type of ``sumSink`` is ``CompletionStage<Integer>`` and because of using ``Keep.right``, the resulting :class:`RunnableGraph`
has also a type parameter of ``CompletionStage<Integer>``.
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: ``RunnableGraph<Future<Integer>>``. Next we call ``run()`` which uses the :class:`ActorMaterializer`
be ``run()``, as indicated by its type: ``RunnableGraph<CompletionStage<Integer>>``. Next we call ``run()`` which uses the :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<Integer>`` which, when completed, will contain the total length of our tweets stream.
In our case this type is ``CompletionStage<Integer>`` 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:`RunnableGraph` may be reused

View file

@ -48,7 +48,7 @@ used for writing stream tests that use familiar :class:`TestProbe` from the
:mod:`akka-testkit` API.
One of the more straightforward tests would be to materialize stream to a
:class:`Future` and then use ``pipe`` pattern to pipe the result of that future
:class:`CompletionStage` and then use ``PatternsCS.pipe`` pattern to pipe the result of that future
to the probe.
.. includecode:: ../code/docs/stream/StreamTestKitDocTest.java#pipeto-testprobe