Changing Doc from Akkas futures to Scalas futures and cleanup of examples. See #2314
This commit is contained in:
parent
042f9f8206
commit
217a9c2cf9
3 changed files with 34 additions and 33 deletions
|
|
@ -6,9 +6,10 @@ Futures (Java)
|
|||
Introduction
|
||||
------------
|
||||
|
||||
In Akka, a `Future <http://en.wikipedia.org/wiki/Futures_and_promises>`_ is a data structure used
|
||||
to retrieve the result of some concurrent operation. This operation is usually performed by an ``Actor`` or
|
||||
by the ``Dispatcher`` directly. This result can be accessed synchronously (blocking) or asynchronously (non-blocking).
|
||||
In Scala, a `Future <http://en.wikipedia.org/wiki/Futures_and_promises>`_ is a data structure used
|
||||
to retrieve the result of some concurrent operation. This result can be accessed synchronously (blocking)
|
||||
or asynchronously (non-blocking). To be able to use this from Java, Akka provides a java friendly interface
|
||||
in ``akka.dispatch.Futures``.
|
||||
|
||||
Execution Contexts
|
||||
------------------
|
||||
|
|
@ -27,7 +28,7 @@ Use with Actors
|
|||
There are generally two ways of getting a reply from an ``UntypedActor``: the first is by a sent message (``actorRef.tell(msg)``),
|
||||
which only works if the original sender was an ``UntypedActor``) and the second is through a ``Future``.
|
||||
|
||||
Using the ``ActorRef``\'s ``ask`` method to send a message will return a Future.
|
||||
Using the ``ActorRef``\'s ``ask`` method to send a message will return a ``Future``.
|
||||
To wait for and retrieve the actual result the simplest method is:
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
|
|
@ -68,7 +69,7 @@ Or failures:
|
|||
Functional Futures
|
||||
------------------
|
||||
|
||||
Akka's ``Future`` has several monadic methods that are very similar to the ones used by ``Scala``'s collections.
|
||||
Scala's ``Future`` has several monadic methods that are very similar to the ones used by ``Scala``'s collections.
|
||||
These allow you to create 'pipelines' or 'streams' that the result will travel through.
|
||||
|
||||
Future is a Monad
|
||||
|
|
@ -81,12 +82,12 @@ The return value of the ``map`` method is another ``Future`` that will contain t
|
|||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: imports2,map
|
||||
|
||||
In this example we are joining two strings together within a Future. Instead of waiting for f1 to complete,
|
||||
In this example we are joining two strings together within a ``Future``. Instead of waiting for f1 to complete,
|
||||
we apply our function that calculates the length of the string using the ``map`` method.
|
||||
Now we have a second Future, f2, that will eventually contain an ``Integer``.
|
||||
When our original ``Future``, f1, completes, it will also apply our function and complete the second Future
|
||||
Now we have a second ``Future``, f2, that will eventually contain an ``Integer``.
|
||||
When our original ``Future``, f1, completes, it will also apply our function and complete the second ``Future``
|
||||
with its result. When we finally ``get`` the result, it will contain the number 10.
|
||||
Our original Future still contains the string "HelloWorld" and is unaffected by the ``map``.
|
||||
Our original ``Future`` still contains the string "HelloWorld" and is unaffected by the ``map``.
|
||||
|
||||
Something to note when using these methods: if the ``Future`` is still being processed when one of these methods are called,
|
||||
it will be the completing thread that actually does the work.
|
||||
|
|
@ -115,7 +116,7 @@ to have this done concurrently, and for that we use ``flatMap``:
|
|||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: flat-map
|
||||
|
||||
Now our second Future is executed concurrently as well. This technique can also be used to combine the results
|
||||
Now our second ``Future`` is executed concurrently as well. This technique can also be used to combine the results
|
||||
of several Futures into a single calculation, which will be better explained in the following sections.
|
||||
|
||||
If you need to do conditional propagation, you can use ``filter``:
|
||||
|
|
@ -157,7 +158,7 @@ That's all it takes!
|
|||
|
||||
|
||||
If the sequence passed to ``fold`` is empty, it will return the start-value, in the case above, that will be empty String.
|
||||
In some cases you don't have a start-value and you're able to use the value of the first completing Future
|
||||
In some cases you don't have a start-value and you're able to use the value of the first completing ``Future``
|
||||
in the sequence as the start-value, you can use ``reduce``, it works like this:
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
|
|
@ -172,7 +173,7 @@ Callbacks
|
|||
---------
|
||||
|
||||
Sometimes you just want to listen to a ``Future`` being completed, and react to that not by creating a new Future, but by side-effecting.
|
||||
For this Akka supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the latter two are specializations of the first.
|
||||
For this Scala supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the latter two are specializations of the first.
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
:include: onSuccess
|
||||
|
|
@ -188,8 +189,8 @@ Ordering
|
|||
|
||||
Since callbacks are executed in any order and potentially in parallel,
|
||||
it can be tricky at the times when you need sequential ordering of operations.
|
||||
But there's a solution! And it's name is ``andThen``, and it creates a new Future with
|
||||
the specified callback, a Future that will have the same result as the Future it's called on,
|
||||
But there's a solution! And it's name is ``andThen``, and it creates a new ``Future`` with
|
||||
the specified callback, a ``Future`` that will have the same result as the ``Future`` it's called on,
|
||||
which allows for ordering like in the following sample:
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocTestBase.java
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ class FutureDocSpec extends AkkaSpec {
|
|||
val f1 = Future {
|
||||
"Hello" + "World"
|
||||
}
|
||||
val f2 = Promise.successful(3).future
|
||||
val f2 = Future.successful(3)
|
||||
val f3 = f1 map { x ⇒
|
||||
f2 map { y ⇒
|
||||
x.length * y
|
||||
|
|
@ -132,7 +132,7 @@ class FutureDocSpec extends AkkaSpec {
|
|||
val f1 = Future {
|
||||
"Hello" + "World"
|
||||
}
|
||||
val f2 = Promise.successful(3).future
|
||||
val f2 = Future.successful(3)
|
||||
val f3 = f1 flatMap { x ⇒
|
||||
f2 map { y ⇒
|
||||
x.length * y
|
||||
|
|
@ -145,7 +145,7 @@ class FutureDocSpec extends AkkaSpec {
|
|||
|
||||
"demonstrate usage of filter" in {
|
||||
//#filter
|
||||
val future1 = Promise.successful(4).future
|
||||
val future1 = Future.successful(4)
|
||||
val future2 = future1.filter(_ % 2 == 0)
|
||||
val result = Await.result(future2, 1 second)
|
||||
result must be(4)
|
||||
|
|
@ -290,8 +290,8 @@ class FutureDocSpec extends AkkaSpec {
|
|||
val msg1 = -1
|
||||
//#try-recover
|
||||
val future = akka.pattern.ask(actor, msg1) recoverWith {
|
||||
case e: ArithmeticException ⇒ Promise.successful(0).future
|
||||
case foo: IllegalArgumentException ⇒ Promise.failed[Int](new IllegalStateException("All br0ken!")).future
|
||||
case e: ArithmeticException ⇒ Future.successful(0)
|
||||
case foo: IllegalArgumentException ⇒ Future.failed[Int](new IllegalStateException("All br0ken!"))
|
||||
}
|
||||
//#try-recover
|
||||
Await.result(future, 1 second) must be(0)
|
||||
|
|
@ -343,7 +343,7 @@ class FutureDocSpec extends AkkaSpec {
|
|||
Await.result(future, 1 second) must be("foo")
|
||||
}
|
||||
{
|
||||
val future = Promise.failed[String](new IllegalStateException("OHNOES")).future
|
||||
val future = Future.failed[String](new IllegalStateException("OHNOES"))
|
||||
//#onFailure
|
||||
future onFailure {
|
||||
case ise: IllegalStateException if ise.getMessage == "OHNOES" ⇒
|
||||
|
|
@ -367,12 +367,12 @@ class FutureDocSpec extends AkkaSpec {
|
|||
}
|
||||
}
|
||||
|
||||
"demonstrate usage of Promise.success & Promise.failed" in {
|
||||
"demonstrate usage of Future.successful & Future.failed" in {
|
||||
//#successful
|
||||
val future = Promise.successful("Yay!").future
|
||||
val future = Future.successful("Yay!")
|
||||
//#successful
|
||||
//#failed
|
||||
val otherFuture = Promise.failed[String](new IllegalArgumentException("Bang!")).future
|
||||
val otherFuture = Future.failed[String](new IllegalArgumentException("Bang!"))
|
||||
//#failed
|
||||
Await.result(future, 1 second) must be("Yay!")
|
||||
intercept[IllegalArgumentException] { Await.result(otherFuture, 1 second) }
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ Futures (Scala)
|
|||
Introduction
|
||||
------------
|
||||
|
||||
In Akka, a `Future <http://en.wikipedia.org/wiki/Futures_and_promises>`_ is a data structure used to
|
||||
retrieve the result of some concurrent operation. This operation is usually performed by an ``Actor``
|
||||
or by the ``Dispatcher`` directly. This result can be accessed synchronously (blocking) or asynchronously (non-blocking).
|
||||
In Scala, a `Future <http://en.wikipedia.org/wiki/Futures_and_promises>`_ is a data structure used to
|
||||
retrieve the result of some concurrent operation. This result can be accessed synchronously (blocking)
|
||||
or asynchronously (non-blocking).
|
||||
|
||||
Execution Contexts
|
||||
------------------
|
||||
|
|
@ -28,7 +28,7 @@ Use With Actors
|
|||
There are generally two ways of getting a reply from an ``Actor``: the first is by a sent message (``actor ! msg``),
|
||||
which only works if the original sender was an ``Actor``) and the second is through a ``Future``.
|
||||
|
||||
Using an ``Actor``\'s ``?`` method to send a message will return a Future. To wait for and retrieve the actual result the simplest method is:
|
||||
Using an ``Actor``\'s ``?`` method to send a message will return a ``Future``. To wait for and retrieve the actual result the simplest method is:
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: ask-blocking
|
||||
|
|
@ -61,7 +61,7 @@ with the return value of the block used to complete the ``Future`` (in this case
|
|||
Unlike a ``Future`` that is returned from an ``Actor``, this ``Future`` is properly typed,
|
||||
and we also avoid the overhead of managing an ``Actor``.
|
||||
|
||||
You can also create already completed Futures using the ``Promise`` companion, which can be either successes:
|
||||
You can also create already completed Futures using the ``Future`` companion, which can be either successes:
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: successful
|
||||
|
|
@ -74,7 +74,7 @@ Or failures:
|
|||
Functional Futures
|
||||
------------------
|
||||
|
||||
Akka's ``Future`` has several monadic methods that are very similar to the ones used by Scala's collections.
|
||||
Scala's ``Future`` has several monadic methods that are very similar to the ones used by Scala's collections.
|
||||
These allow you to create 'pipelines' or 'streams' that the result will travel through.
|
||||
|
||||
Future is a Monad
|
||||
|
|
@ -185,20 +185,20 @@ That's all it takes!
|
|||
|
||||
|
||||
If the sequence passed to ``fold`` is empty, it will return the start-value, in the case above, that will be 0.
|
||||
In some cases you don't have a start-value and you're able to use the value of the first completing Future in the sequence
|
||||
In some cases you don't have a start-value and you're able to use the value of the first completing ``Future`` in the sequence
|
||||
as the start-value, you can use ``reduce``, it works like this:
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: reduce
|
||||
|
||||
Same as with ``fold``, the execution will be done asynchronously when the last of the Future is completed,
|
||||
Same as with ``fold``, the execution will be done asynchronously when the last of the ``Future`` is completed,
|
||||
you can also parallelize it by chunking your futures into sub-sequences and reduce them, and then reduce the reduced results again.
|
||||
|
||||
Callbacks
|
||||
---------
|
||||
|
||||
Sometimes you just want to listen to a ``Future`` being completed, and react to that not by creating a new Future, but by side-effecting.
|
||||
For this Akka supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the latter two are specializations of the first.
|
||||
Sometimes you just want to listen to a ``Future`` being completed, and react to that not by creating a new ``Future``, but by side-effecting.
|
||||
For this Scala supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the latter two are specializations of the first.
|
||||
|
||||
.. includecode:: code/docs/future/FutureDocSpec.scala
|
||||
:include: onSuccess
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue