.. _futures-java: Futures =============== Introduction ------------ In the Scala Standard Library, a `Future `_ 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``. See also :ref:`actor-java-lambda` for Java compatibility. Execution Contexts ------------------ In order to execute callbacks and operations, Futures need something called an ``ExecutionContext``, which is very similar to a ``java.util.concurrent.Executor``. if you have an ``ActorSystem`` in scope, it will use its default dispatcher as the ``ExecutionContext``, or you can use the factory methods provided by the ``ExecutionContexts`` class to wrap ``Executors`` and ``ExecutorServices``, or even create your own. .. includecode:: code/docs/future/FutureDocTest.java :include: imports1,imports7 .. includecode:: code/docs/future/FutureDocTest.java :include: diy-execution-context 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, sender)``), 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``. To wait for and retrieve the actual result the simplest method is: .. includecode:: code/docs/future/FutureDocTest.java :include: imports1 .. includecode:: code/docs/future/FutureDocTest.java :include: ask-blocking This will cause the current thread to block and wait for the ``UntypedActor`` to 'complete' the ``Future`` with it's reply. Blocking is discouraged though as it can cause performance problem. The blocking operations are located in ``Await.result`` and ``Await.ready`` to make it easy to spot where blocking occurs. Alternatives to blocking are discussed further within this documentation. Also note that the ``Future`` returned by an ``UntypedActor`` is a ``Future`` since an ``UntypedActor`` is dynamic. That is why the cast to ``String`` is used in the above sample. .. warning:: ``Await.result`` and ``Await.ready`` are provided for exceptional situations where you **must** block, a good rule of thumb is to only use them if you know why you **must** block. For all other cases, use asynchronous composition as described below. To send the result of a ``Future`` to an ``Actor``, you can use the ``pipe`` construct: .. includecode:: code/docs/future/FutureDocTest.java :include: pipe-to Use Directly ------------ A common use case within Akka is to have some computation performed concurrently without needing the extra utility of an ``UntypedActor``. If you find yourself creating a pool of ``UntypedActor``\s for the sole reason of performing a calculation in parallel, there is an easier (and faster) way: .. includecode:: code/docs/future/FutureDocTest.java :include: imports2 .. includecode:: code/docs/future/FutureDocTest.java :include: future-eval In the above code the block passed to ``future`` will be executed by the default ``Dispatcher``, with the return value of the block used to complete the ``Future`` (in this case, the result would be the string: "HelloWorld"). Unlike a ``Future`` that is returned from an ``UntypedActor``, this ``Future`` is properly typed, and we also avoid the overhead of managing an ``UntypedActor``. You can also create already completed Futures using the ``Futures`` class, which can be either successes: .. includecode:: code/docs/future/FutureDocTest.java :include: successful Or failures: .. includecode:: code/docs/future/FutureDocTest.java :include: failed It is also possible to create an empty ``Promise``, to be filled later, and obtain the corresponding ``Future``: .. includecode:: code/docs/future/FutureDocTest.java#promise For these examples ``PrintResult`` is defined as follows: .. includecode:: code/docs/future/FutureDocTest.java :include: print-result Functional Futures ------------------ 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 ^^^^^^^^^^^^^^^^^ The first method for working with ``Future`` functionally is ``map``. This method takes a ``Mapper`` which performs some operation on the result of the ``Future``, and returning a new result. The return value of the ``map`` method is another ``Future`` that will contain the new result: .. includecode:: code/docs/future/FutureDocTest.java :include: imports2 .. includecode:: code/docs/future/FutureDocTest.java :include: map 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`` 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``. Something to note when using these methods: passed work is always dispatched on the provided ``ExecutionContext``. Even if the ``Future`` has already been completed, when one of these methods is called. Composing Futures ^^^^^^^^^^^^^^^^^ It is very often desirable to be able to combine different Futures with each other, below are some examples on how that can be done in a non-blocking fashion. .. includecode:: code/docs/future/FutureDocTest.java :include: imports3 .. includecode:: code/docs/future/FutureDocTest.java :include: sequence To better explain what happened in the example, ``Future.sequence`` is taking the ``Iterable>`` and turning it into a ``Future>``. We can then use ``map`` to work with the ``Iterable`` directly, and we aggregate the sum of the ``Iterable``. The ``traverse`` method is similar to ``sequence``, but it takes a sequence of ``A`` and applies a function from ``A`` to ``Future`` and returns a ``Future>``, enabling parallel ``map`` over the sequence, if you use ``Futures.future`` to create the ``Future``. .. includecode:: code/docs/future/FutureDocTest.java :include: imports4 .. includecode:: code/docs/future/FutureDocTest.java :include: traverse It's as simple as that! Then there's a method that's called ``fold`` that takes a start-value, a sequence of ``Future``:s and a function from the type of the start-value, a timeout, and the type of the futures and returns something with the same type as the start-value, and then applies the function to all elements in the sequence of futures, non-blockingly, the execution will be started when the last of the Futures is completed. .. includecode:: code/docs/future/FutureDocTest.java :include: imports5 .. includecode:: code/docs/future/FutureDocTest.java :include: fold 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 the sequence as the start-value, you can use ``reduce``, it works like this: .. includecode:: code/docs/future/FutureDocTest.java :include: imports6 .. includecode:: code/docs/future/FutureDocTest.java :include: reduce Same as with ``fold``, the execution will be started when the last of the Futures is completed, you can also parallelize it by chunking your futures into sub-sequences and reduce them, and then reduce the reduced results again. This is just a sample of what can be done. 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 Scala supports ``onComplete``, ``onSuccess`` and ``onFailure``, of which the last two are specializations of the first. .. includecode:: code/docs/future/FutureDocTest.java :include: onSuccess .. includecode:: code/docs/future/FutureDocTest.java :include: onFailure .. includecode:: code/docs/future/FutureDocTest.java :include: onComplete 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, which allows for ordering like in the following sample: .. includecode:: code/docs/future/FutureDocTest.java :include: and-then Auxiliary methods ----------------- ``Future`` ``fallbackTo`` combines 2 Futures into a new ``Future``, and will hold the successful value of the second ``Future`` if the first ``Future`` fails. .. includecode:: code/docs/future/FutureDocTest.java :include: fallback-to You can also combine two Futures into a new ``Future`` that will hold a tuple of the two Futures successful results, using the ``zip`` operation. .. includecode:: code/docs/future/FutureDocTest.java :include: zip Exceptions ---------- Since the result of a ``Future`` is created concurrently to the rest of the program, exceptions must be handled differently. It doesn't matter if an ``UntypedActor`` or the dispatcher is completing the ``Future``, if an ``Exception`` is caught the ``Future`` will contain it instead of a valid result. If a ``Future`` does contain an ``Exception``, calling ``Await.result`` will cause it to be thrown again so it can be handled properly. It is also possible to handle an ``Exception`` by returning a different result. This is done with the ``recover`` method. For example: .. includecode:: code/docs/future/FutureDocTest.java :include: recover In this example, if the actor replied with a ``akka.actor.Status.Failure`` containing the ``ArithmeticException``, our ``Future`` would have a result of 0. The ``recover`` method works very similarly to the standard try/catch blocks, so multiple ``Exception``\s can be handled in this manner, and if an ``Exception`` is not handled this way it will behave as if we hadn't used the ``recover`` method. You can also use the ``recoverWith`` method, which has the same relationship to ``recover`` as ``flatMap`` has to ``map``, and is use like this: .. includecode:: code/docs/future/FutureDocTest.java :include: try-recover After ----- ``akka.pattern.Patterns.after`` makes it easy to complete a ``Future`` with a value or exception after a timeout. .. includecode:: code/docs/future/FutureDocTest.java :include: imports8 .. includecode:: code/docs/future/FutureDocTest.java :include: after