Interface Future<T>

  • Type Parameters:
    T - The type this Future will hold as result

    public interface Future<T>
    A Future that will hold the result of an asynchronous computation.
    The Future is paired with an instance of Promise which is also the way to get hold of a Future.
    One can see a Future as a holder for a value-to-be, not yet available but accessible sometime in the future.
    The preferred way to get hold of the value-to-be is to register a listener on any of the provided listener types since this allows for asynchronous non-blocking operations. It is possible to register multiple listeners to several/same listener type.
    One can register a listener both before and after a Future has been completed.
    Should the Future already be completed when the listener is added it is fired immediately.
    The guarantee is that a listener is only fired once.

    All operations on this class are non-blocking, i.e. allowing for proper asynchronous/non-blocking programming patterns.
    With one exception, for situations where it is necessary to maintain synchronous/blocking behavior the method result(long, TimeUnit) is provided.

    For real short and consistent programming one can use the apply(ThrowableFunction0) method to provide a function that will be executed in the future.
    The result of the function will be reported to the Future returned by the method.
     Future<Integer> resultSuccess = Future.apply(() -> 9 / 3); // The Future will at some point contain: Success(3)
     Future<Integer> resultFailure = Future.apply(() -> 9 / 0); // The Future will at some point contain: Failure(ArithmeticException)
     
    Since:
    1.2
    • Method Summary

      All Methods Static Methods Instance Methods Abstract Methods Default Methods 
      Modifier and Type Method Description
      static <T> Future<T> apply​(ThrowableFunction0<T> function)
      Allows for easy creation of asynchronous computations that will be executed in the future.
      static <T> Future<T> apply​(ThrowableFunction0<T> function, Executor executor)
      Allows for easy creation of asynchronous computations that will be executed in the future.
      static <T> Future<T> failed​(java.lang.Throwable throwable)
      Creates a failed Future with the provided Throwable.
      Future<T> filter​(java.util.function.Predicate<T> predicate)
      Creates a new Future that will filter the successful value of this instance once it is completed.
      <R> Future<R> flatMap​(ThrowableFunction1<T,​Future<R>> function)
      Creates a new Future that will hold the mapped successful value of this instance once it is completed.
      void forEach​(java.util.function.Consumer<T> consumer)
      Asynchronously processes the value in the Future once it is available.
      static <T> Future<T> fromTry​(Try<T> result)
      Creates a completed Future with the provided Try.
      boolean isCompleted()
      Check if this Future is completed, with a value or an exception.
      <R> Future<R> map​(ThrowableFunction1<T,​R> function)
      Creates a new Future that will hold the mapped successful value of this instance once it is completed.
      void onComplete​(java.util.function.Consumer<Try<T>> completeHandler)
      Register a handler to be invoked if the Future gets completed with a value or a failure.
      void onFailure​(java.util.function.Consumer<java.lang.Throwable> failureHandler)
      Register a handler to be invoked if the Future gets completed with an exception.
      void onSuccess​(java.util.function.Consumer<T> successHandler)
      Register a handler to be invoked if the Future gets completed with a value.
      Future<T> ready​(long duration, java.util.concurrent.TimeUnit timeUnit)
      Blocks and waits for this Future to complete.
      default Future<T> ready​(java.time.Duration duration)
      Blocks and waits for this Future to complete.
      Future<T> recover​(ThrowableFunction1<java.lang.Throwable,​T> recoverFunction)
      Creates a new Future that in case this Future is a 'failure' will apply the function to recover the 'failure' to a 'success'.
      T result​(long duration, java.util.concurrent.TimeUnit timeUnit)
      Blocks and waits for this Future to complete.
      default T result​(java.time.Duration duration)
      Blocks and waits for this Future to complete.
      static <T> Future<java.util.stream.Stream<T>> sequence​(java.util.stream.Stream<Future<T>> stream)
      Turns a Stream of Futures into a single Future containing a Stream with all the results from the Futures.
      static <T> Future<T> successful​(T value)
      Creates a successful Future with the provided value.
      <R> Future<R> transform​(ThrowableFunction1<T,​R> onSuccess, ThrowableFunction1<java.lang.Throwable,​java.lang.Throwable> onFailure)
      Creates a new Future that will hold the transformed successful value of this instance once it is completed.
      static <T,​R>
      Future<java.util.stream.Stream<R>>
      traverse​(java.util.stream.Stream<T> stream, java.util.function.Function<T,​Future<R>> function)
      Takes a Stream of values and applies the provided function to them in parallel resulting in a Future containing a Stream with the mapped values.
      Option<Try<T>> value()
      The current (completed or not) value of the future.
    • Method Detail

      • apply

        static <T> Future<T> apply​(ThrowableFunction0<T> function)
        Allows for easy creation of asynchronous computations that will be executed in the future.
        The method will use the Executors.getDefault() method to get hold of the default Executor to use for executing the provided job.
        Simple examples:
         Future<Integer> resultSuccess = Future.apply(() -> 9 / 3); // The Future will at some point contain: Success(3)
         Future<Integer> resultFailure = Future.apply(() -> 9 / 0); // The Future will at some point contain: Failure(ArithmeticException)
         
        Type Parameters:
        T - The type for the Future
        Parameters:
        function - The function to render either the value T or raise an exception.
        Returns:
        The future that will hold the result provided by the function
        Since:
        1.3
      • apply

        static <T> Future<T> apply​(ThrowableFunction0<T> function,
                                   Executor executor)
        Allows for easy creation of asynchronous computations that will be executed in the future.
        The method will use the provided Executor for executing the provided job.
        Simple examples:
         Future<Integer> resultSuccess = Future.apply(() -> 9 / 3, someExecutor); // The Future will at some point contain: Success(3)
         Future<Integer> resultFailure = Future.apply(() -> 9 / 0, someExecutor); // The Future will at some point contain: Failure(ArithmeticException)
         
        Type Parameters:
        T - The type for the Future
        Parameters:
        function - The function to render either the value T or raise an exception.
        executor - The executor to use to compute/execute the Future holding the provided function
        Returns:
        The future that will hold the result provided by the function
        Since:
        1.4
      • failed

        static <T> Future<T> failed​(java.lang.Throwable throwable)
        Creates a failed Future with the provided Throwable.
        Type Parameters:
        T - The type for the Future
        Parameters:
        throwable - The throwable to complete the Future with.
        Returns:
        The completed Future holding the provided Throwable
        Since:
        1.5
      • successful

        static <T> Future<T> successful​(T value)
        Creates a successful Future with the provided value.
        Type Parameters:
        T - The type for the Future
        Parameters:
        value - The value to complete the Future with.
        Returns:
        The completed Future holding the provided value
        Since:
        1.5
      • fromTry

        static <T> Future<T> fromTry​(Try<T> result)
        Creates a completed Future with the provided Try.
        The Future can therefore be either Success or Failure.
        Type Parameters:
        T - The type for the Future
        Parameters:
        result - The Success/Failure to complete the Future with.
        Returns:
        The completed Future holding the provided result
        Since:
        1.5
      • sequence

        static <T> Future<java.util.stream.Stream<T>> sequence​(java.util.stream.Stream<Future<T>> stream)
        Turns a Stream of Futures into a single Future containing a Stream with all the results from the Futures.
        Allows for easy management of multiple Futures.
        Note, should any Future in the Stream fail the entire sequence fails.
        An empty input Stream will result in a Future containing an empty result Stream.
        Type Parameters:
        T - The type for the Stream in the resulting Future
        Parameters:
        stream - The Stream with Futures
        Returns:
        A single Future containing the Stream of results
        Since:
        1.5
      • traverse

        static <T,​R> Future<java.util.stream.Stream<R>> traverse​(java.util.stream.Stream<T> stream,
                                                                       java.util.function.Function<T,​Future<R>> function)
        Takes a Stream of values and applies the provided function to them in parallel resulting in a Future containing a Stream with the mapped values.
        Can be used to run a mapping operation in parallel e.g.:
         import static javascalautils.FutureCompanion.Future;
        
         Stream<String> stream = ...; // Stream with strings
         Future<Stream<Integer>> future = Future.traverse(stream, v -> Future(() -> v.length()));
         
        Type Parameters:
        T - The type for the input Stream
        R - The type for the Stream in the resulting Future
        Parameters:
        stream - The Stream with values
        function - The function to be applied to all values of the Stream
        Returns:
        A single Future containing the Stream of results
        Since:
        1.5
      • isCompleted

        boolean isCompleted()
        Check if this Future is completed, with a value or an exception.
        Returns:
        true if completed, false otherwise.
      • value

        Option<Try<T>> value()
        The current (completed or not) value of the future.
        This is a non-blocking method, it will return the current state/value of the Future.
        There are three possible outcomes:
        • The future has not been completed -> None is returned
        • The execution of the Future was successful -> Some with a Success containing the value of the executed job
        • The execution failed and an exception was reported -> Some with a Failure containing the Throwable
        Returns:
        An Option with the result.
      • onFailure

        void onFailure​(java.util.function.Consumer<java.lang.Throwable> failureHandler)
        Register a handler to be invoked if the Future gets completed with an exception.
        If the Future has already been completed the notification will happen in the current thread.
        Multiple handlers can be registered, without any guarantee of notification order.
        Each individual event handler will only be invoked once.
        Parameters:
        failureHandler - Consumer to invoke.
      • onSuccess

        void onSuccess​(java.util.function.Consumer<T> successHandler)
        Register a handler to be invoked if the Future gets completed with a value.
        If the Future has already been completed the notification will happen in the current thread.
        Multiple handlers can be registered, without any guarantee of notification order.
        Each individual event handler will only be invoked once.
        Parameters:
        successHandler - Consumer to invoke.
      • onComplete

        void onComplete​(java.util.function.Consumer<Try<T>> completeHandler)
        Register a handler to be invoked if the Future gets completed with a value or a failure.
        If the Future has already been completed the notification will happen in the current thread.
        Multiple handlers can be registered, without any guarantee of notification order.
        Each individual event handler will only be invoked once.
        Parameters:
        completeHandler - Consumer to invoke.
      • forEach

        void forEach​(java.util.function.Consumer<T> consumer)
        Asynchronously processes the value in the Future once it is available.
        Only successful Futures are reported to the consumer.
        This is pretty much the same as onSuccess(Consumer) but is here for completion keeping a consistent look and feel.
        Parameters:
        consumer - The consumer to digest the result
      • map

        <R> Future<R> map​(ThrowableFunction1<T,​R> function)
        Creates a new Future that will hold the mapped successful value of this instance once it is completed.
        Unsuccessful Futures will not be mapped, they are kept unsuccessful as they are.
        Type Parameters:
        R - The type for the value held by the mapped future
        Parameters:
        function - The function to apply
        Returns:
        The mapped Future
      • flatMap

        <R> Future<R> flatMap​(ThrowableFunction1<T,​Future<R>> function)
        Creates a new Future that will hold the mapped successful value of this instance once it is completed.
        Unsuccessful Futures will not be mapped, they are kept unsuccessful as they are.
        Type Parameters:
        R - The type for the value held by the mapped future
        Parameters:
        function - The function to apply
        Returns:
        The mapped Future
      • filter

        Future<T> filter​(java.util.function.Predicate<T> predicate)
        Creates a new Future that will filter the successful value of this instance once it is completed.
        The possible outcomes are:
        • This Future is successful -> predicate matches -> The filtered future is completed with the value.
        • This Future is successful -> predicate fails -> The filtered future is failed with NoSuchElementException.
        • This Future is failure -> The failure is passed on to the filtered Future.
        Parameters:
        predicate - The predicate to apply
        Returns:
        The filtered Future
      • transform

        <R> Future<R> transform​(ThrowableFunction1<T,​R> onSuccess,
                                ThrowableFunction1<java.lang.Throwable,​java.lang.Throwable> onFailure)
        Creates a new Future that will hold the transformed successful value of this instance once it is completed.
        Successful futures are transformed with the onSuccess function and unsuccessful/failure futures are transformed with onFailure.
        Type Parameters:
        R - The type for the value held by the mapped future
        Parameters:
        onSuccess - The function to apply on a 'successful' result
        onFailure - The function to apply on a 'failure' result
        Returns:
        The mapped Future
        Since:
        1.3
      • recover

        Future<T> recover​(ThrowableFunction1<java.lang.Throwable,​T> recoverFunction)
        Creates a new Future that in case this Future is a 'failure' will apply the function to recover the 'failure' to a 'success'.
        Should this Future be a 'success' the value is propagated as-is.
        E.g.
         Future<String> future = ...
         Future<String> recovered = future.recover(t -> t.getMessage());
         
        In case of 'future' being successful then that value is passed on to 'recovered', in case of failure then the recover function kicks in and returns the message from the throwable.
        Parameters:
        recoverFunction - The function to apply in case of a 'failure'
        Returns:
        The recovered Future
        Since:
        1.3
      • result

        T result​(long duration,
                 java.util.concurrent.TimeUnit timeUnit)
          throws java.lang.Throwable,
                 java.util.concurrent.TimeoutException
        Blocks and waits for this Future to complete.
        Returns the result of a successful Future or throws the exception in case of a failure.
        The methods blocks for at most the provided duration.
        If the Future is already completed the method returns immediately.
        Parameters:
        duration - The duration to block
        timeUnit - The unit for the duration
        Returns:
        The result in case successful
        Throws:
        java.lang.Throwable - The error reported in case of a failure
        java.util.concurrent.TimeoutException - In case the waiting time is passed
      • result

        default T result​(java.time.Duration duration)
                  throws java.lang.Throwable,
                         java.util.concurrent.TimeoutException
        Blocks and waits for this Future to complete.
        Returns the result of a successful Future or throws the exception in case of a failure.
        The methods blocks for at most the provided duration.
        If the Future is already completed the method returns immediately.
        Parameters:
        duration - The duration to block
        Returns:
        The result in case successful
        Throws:
        java.lang.Throwable - The error reported in case of a failure
        java.util.concurrent.TimeoutException - In case the waiting time is passed
        Since:
        1.8
      • ready

        Future<T> ready​(long duration,
                        java.util.concurrent.TimeUnit timeUnit)
                 throws java.util.concurrent.TimeoutException,
                        java.lang.InterruptedException
        Blocks and waits for this Future to complete.
        As opposed to result this method will not return the value or throw the exception of the Future.
        The method will upon completion returns this.
        The purpose of the method is to provide a blocking mechanism waiting for the Future to complete.
        Any action on the Future's result is then left to the developer to manage.
        Parameters:
        duration - The duration to block
        timeUnit - The unit for the duration
        Returns:
        this if the Future completes within the specified time
        Throws:
        java.util.concurrent.TimeoutException - In case the waiting time is passed
        java.lang.InterruptedException - In case the thread gets interrupted during the wait
        Since:
        1.8
      • ready

        default Future<T> ready​(java.time.Duration duration)
                         throws java.util.concurrent.TimeoutException,
                                java.lang.InterruptedException
        Blocks and waits for this Future to complete.
        As opposed to result this method will not return the value or throw the exception of the Future.
        The method will upon completion returns this.
        The purpose of the method is to provide a blocking mechanism waiting for the Future to complete.
        Any action on the Future's result is then left to the developer to manage.
        Parameters:
        duration - The duration to block
        Returns:
        this if the Future completes within the specified time
        Throws:
        java.util.concurrent.TimeoutException - In case the waiting time is passed
        java.lang.InterruptedException - In case the thread gets interrupted during the wait
        Since:
        1.8