<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Valery Silaev</title>
    <description>The latest articles on Forem by Valery Silaev (@vsilaev).</description>
    <link>https://forem.com/vsilaev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F130801%2Fcb947693-f6dc-4a13-b0e1-b8b74b116d91.jpeg</url>
      <title>Forem: Valery Silaev</title>
      <link>https://forem.com/vsilaev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/vsilaev"/>
    <language>en</language>
    <item>
      <title>Tascalate Concurrent - Filling the Gaps in CompletableFuture API (Part 1)</title>
      <dc:creator>Valery Silaev</dc:creator>
      <pubDate>Fri, 25 Jan 2019 11:15:44 +0000</pubDate>
      <link>https://forem.com/vsilaev/tascalate-concurrent---filling-the-gaps-in-completablefuture-api-part-1-7lm</link>
      <guid>https://forem.com/vsilaev/tascalate-concurrent---filling-the-gaps-in-completablefuture-api-part-1-7lm</guid>
      <description>&lt;p&gt;&lt;a href="https://github.com/vsilaev/tascalate-concurrent" rel="noopener noreferrer"&gt;Tascalate Concurrent&lt;/a&gt; library provides an implementation of the &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html" rel="noopener noreferrer"&gt;CompletionStage&lt;/a&gt; interface and related classes these are designed to support long-running blocking tasks (typically, I/O bound). This functionality augments the sole Java 8 built-in implementation, &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt;, that is primarily supports computational tasks. Also, the library helps with numerous asynchronous programing challenges like handling timeouts, retry/poll functionality, orchestrating results of multiple concurrent computations and similar.&lt;/p&gt;

&lt;p&gt;The library is shipped as a multi-release JAR and may be used both with Java 8 as a classpath library or with Java 9+ as a module.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why a CompletableFuture is not enough?
&lt;/h1&gt;

&lt;p&gt;There are several shortcomings associated with &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt; implementation that complicate its usage for real-life asynchronous programming, especially when you have to work with I/O-bound interruptible tasks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;code&gt;CompletableFuture.cancel()&lt;/code&gt; &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#cancel-boolean-" rel="noopener noreferrer"&gt;method&lt;/a&gt; does not interrupt underlying thread; it merely puts future to exceptionally completed state. So even if you use any blocking calls inside functions passed to &lt;code&gt;thenApplyAsync&lt;/code&gt; / &lt;code&gt;thenAcceptAsync&lt;/code&gt; / etc - these functions will run till the end and never will be interrupted. Please see &lt;a href="http://www.nurkiewicz.com/2015/03/completablefuture-cant-be-interrupted.html" rel="noopener noreferrer"&gt;CompletableFuture can't be interrupted&lt;/a&gt; by Tomasz Nurkiewicz.&lt;/li&gt;
&lt;li&gt; By default, all &lt;code&gt;*Async&lt;/code&gt; composition methods of &lt;code&gt;CompletableFutrure&lt;/code&gt; use &lt;code&gt;ForkJoinPool.commonPool()&lt;/code&gt; (&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html#commonPool--" rel="noopener noreferrer"&gt;see here&lt;/a&gt;) unless explicit &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html" rel="noopener noreferrer"&gt;Executor&lt;/a&gt; is specified. This thread pool is shared between all &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt;-s and all parallel streams across all applications deployed on the same JVM. This hard-coded, unconfigurable thread pool is completely outside of application developers' control, hard to monitor and scale. Therefore, in robust real-life applications you should always specify your own &lt;code&gt;Executor&lt;/code&gt;. With API enhancements in Java 9+, you can fix this drawback, but it will require some custom coding.&lt;/li&gt;
&lt;li&gt; Additionally, built-in Java 8 concurrency classes provides pretty inconvenient API to combine several &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html" rel="noopener noreferrer"&gt;CompletionStage&lt;/a&gt;-s. &lt;code&gt;CompletableFuture.allOf&lt;/code&gt; / &lt;code&gt;CompletableFuture.anyOf&lt;/code&gt; methods accept only &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt; as arguments; you have no mechanism to combine arbitrary &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html" rel="noopener noreferrer"&gt;CompletionStage&lt;/a&gt;-s without converting them to &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt; first. Also, the return type of the aforementioned &lt;code&gt;CompletableFuture.allOf&lt;/code&gt; is declared as &lt;code&gt;CompletableFuture&amp;lt;Void&amp;gt;&lt;/code&gt; - hence you are unable to extract conveniently individual results of the each future supplied. &lt;code&gt;CompletableFuture.anyOf&lt;/code&gt; is even worse in this regard; for more details please read on here: &lt;a href="http://www.nurkiewicz.com/2013/05/java-8-completablefuture-in-action.html" rel="noopener noreferrer"&gt;CompletableFuture in Action&lt;/a&gt; (see Shortcomings) by Tomasz Nurkiewicz.&lt;/li&gt;
&lt;li&gt;Support for timeouts/delays was introduced to &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt; only in Java 9, so still widely supported applications running on Java 8 are left out without this important functionality. Plus, some design decisions like using delayed executors instead of 'delay' operator, are somewhat questionable.
There are numerous free open-source libraries that address some of the aforementioned shortcomings. However, none of them provides implementation of interruptible &lt;code&gt;CompletionStage&lt;/code&gt; and no one solves &lt;em&gt;all&lt;/em&gt; of the issues coherently.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  How to use?
&lt;/h1&gt;

&lt;p&gt;To use a library you have to add a single Maven dependency&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;net.tascalate.concurrent&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;net.tascalate.concurrent.lib&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.7.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  What is inside?
&lt;/h1&gt;
&lt;h2&gt;
  
  
  1.   Promise interface
&lt;/h2&gt;

&lt;p&gt;This is the core interface of the Tascalate Concurrent library. It may be best described by the formula:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nc"&gt;Future&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I.e., it combines both blocking &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html" rel="noopener noreferrer"&gt;Future&lt;/a&gt;’s API, including &lt;code&gt;cancel(boolean mayInterruptIfRunning)&lt;/code&gt; &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Future.html#cancel-boolean-" rel="noopener noreferrer"&gt;method&lt;/a&gt;, &lt;em&gt;AND&lt;/em&gt; composition capabilities of &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html" rel="noopener noreferrer"&gt;CompletionStage&lt;/a&gt;’s API. Importantly, all composition methods of &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html" rel="noopener noreferrer"&gt;CompletionStage&lt;/a&gt; API (&lt;code&gt;thenAccept&lt;/code&gt;, &lt;code&gt;thenCombine&lt;/code&gt;, &lt;code&gt;whenComplete&lt;/code&gt; etc.) are re-declared to return &lt;code&gt;Promise&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;The decision to introduce an interface that merges &lt;code&gt;CompletionStage&lt;/code&gt; and &lt;code&gt;Future&lt;/code&gt; is aligned with the design of &lt;code&gt;CompletableFuture&lt;/code&gt; API.  In addition, several useful methods of &lt;code&gt;CompletableFuture&lt;/code&gt; API are added as well:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;getNow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;valueIfAbsent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;CancellationException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CompletionException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;getNow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;valueIfAbsent&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;CancellationException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CompletionException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;CancellationException&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CompletionException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;So it should be pretty straightforward to use the &lt;code&gt;Promise&lt;/code&gt; as a drop-in replacement for the &lt;code&gt;CompletableFuture&lt;/code&gt; in many cases.&lt;/p&gt;

&lt;p&gt;Besides this, there are numerous operators in the &lt;code&gt;Promise&lt;/code&gt; API to work with timeouts and delays, to override default asynchronous executor and similar. All of them will be discussed later.&lt;/p&gt;

&lt;p&gt;When discussing &lt;code&gt;Promise&lt;/code&gt; interface, it's mandatory to mention the accompanying class &lt;code&gt;Promises&lt;/code&gt; that provides several useful methods to adapt third-party &lt;code&gt;CompletionStage&lt;/code&gt; (including the standard &lt;code&gt;CompletableFuture&lt;/code&gt;) to the &lt;code&gt;Promise&lt;/code&gt; API. First, there are two unit operations to create successfully/faulty settled &lt;code&gt;Promise&lt;/code&gt;-es:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;failure&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;exception&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Second, there is an adapter method &lt;code&gt;from&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It behaves as the following: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;If the supplied &lt;code&gt;stage&lt;/code&gt; is already a &lt;code&gt;Promise&lt;/code&gt; then it is returned unchanged&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;stage&lt;/code&gt; is a &lt;code&gt;CompletableFuture&lt;/code&gt; then a specially-tailored wrapper is returned.&lt;/li&gt;
&lt;li&gt;If &lt;code&gt;stage&lt;/code&gt; additionally implements &lt;code&gt;Future&lt;/code&gt; then specialized wrapper is returned that delegates all the blocking methods defined in &lt;code&gt;Future&lt;/code&gt; API&lt;/li&gt;
&lt;li&gt;Otherwise generic wrapper is created with good-enough implementation of blocking &lt;code&gt;Future&lt;/code&gt; API atop of asynchronous &lt;code&gt;CompletionStage&lt;/code&gt; API.
To summarize, the returned wrapper delegates as much as possible functionality to the supplied &lt;code&gt;stage&lt;/code&gt; and &lt;em&gt;never&lt;/em&gt; resorts to &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html#toCompletableFuture--" rel="noopener noreferrer"&gt;CompletionStage.toCompletableFuture&lt;/a&gt; because in Java 8 API it's an optional method. From documentation: "A CompletionStage implementation that does not choose to interoperate with others may throw UnsupportedOperationException." (this text was dropped in Java 9+). In general, Tascalate Concurrent library does not depend on this method and should be interoperable with any minimal (but valid) &lt;code&gt;CompletionStage&lt;/code&gt; implementation.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's important to emphasize, that &lt;code&gt;Promise&lt;/code&gt;-s returned from &lt;code&gt;Promises.success&lt;/code&gt;, &lt;code&gt;Promises.failure&lt;/code&gt; and &lt;code&gt;Promises.from&lt;/code&gt; methods are cancellable in the same way as &lt;code&gt;CompletableFuture&lt;/code&gt;, but are not interruptible in general, while interruption depends on a concrete implementation. Next we discuss the concrete implementation of an interruptible &lt;code&gt;Promise&lt;/code&gt; provided by the Tascalate Concurrent library -- the &lt;code&gt;CompletableTask&lt;/code&gt; class.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. CompletableTask
&lt;/h2&gt;

&lt;p&gt;This is why this project was ever started. &lt;code&gt;CompletableTask&lt;/code&gt; is the implementation of the &lt;code&gt;Promise&lt;/code&gt; API for long-running blocking tasks.&lt;br&gt;
Typically, to create a &lt;code&gt;CompletableTask&lt;/code&gt;, you should submit &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html" rel="noopener noreferrer"&gt;Supplier&lt;/a&gt; / &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/lang/Runnable.html" rel="noopener noreferrer"&gt;Runnable&lt;/a&gt; to the &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html" rel="noopener noreferrer"&gt;Executor&lt;/a&gt; right away, in a similar way as with &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="noopener noreferrer"&gt;CompletableFuture&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;SomeValue&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;blockingCalculationOfSomeValue&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;runAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;someIoBoundMethod&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;blockingCalculationOfSomeValue&lt;/code&gt; and &lt;code&gt;someIoBoundMethod&lt;/code&gt; in the example above can have I/O code, work with blocking queues, do blocking get on regular Java-s &lt;code&gt;Future&lt;/code&gt;-s and alike. If at later time you decide to cancel either of the returned promises then corresponding &lt;code&gt;blockingCalculationOfSomeValue&lt;/code&gt; and &lt;code&gt;someIoBoundMethod&lt;/code&gt; will be interrupted (if not completed yet).&lt;/p&gt;

&lt;p&gt;In the realm of I/O-related functionality, failures like connection time-outs, missing or locked files are pretty common, and checked exceptions mechanism is used frequently to signal failures. Therefore the library provides an entry point to the API that accepts &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Callable.html" rel="noopener noreferrer"&gt;Callable&lt;/a&gt; instead of &lt;code&gt;Supplier&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Notice the checked exception in the method signature&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;loadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;IOException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;//load file content;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="nc"&gt;ExecutorService&lt;/span&gt; &lt;span class="n"&gt;executorService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Executors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;contentPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;submit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;loadFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"./myfile.dat"&lt;/span&gt;&lt;span class="o"&gt;)),&lt;/span&gt; 
    &lt;span class="n"&gt;executorService&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Additionally, there are 2 unit operations to create a &lt;code&gt;CompletableTask&lt;/code&gt;:&lt;br&gt;
a. &lt;code&gt;CompletableTask.asyncOn(Executor executor)&lt;/code&gt;&lt;br&gt;
Returns an already-completed null-valued &lt;code&gt;Promise&lt;/code&gt; that is "bound" to the specified executor. I.e. any function passed to asynchronous composition methods of &lt;code&gt;Promise&lt;/code&gt; (like &lt;code&gt;thenApplyAsync&lt;/code&gt; / &lt;code&gt;thenAcceptAsync&lt;/code&gt; / &lt;code&gt;whenCompleteAsync&lt;/code&gt; etc.) will be executed using this executor unless executor is overridden via explicit composition method parameter. Moreover, any nested composition calls will use same executor, if it’s not redefined via explicit composition method parameter:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asyncOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myExecutor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myValueGenerator&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenAcceptAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myConsumer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenRunAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAction&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;All of &lt;code&gt;myValueGenerator&lt;/code&gt;, &lt;code&gt;myConsumer&lt;/code&gt;, &lt;code&gt;myAction&lt;/code&gt; will be executed using &lt;code&gt;myExecutor&lt;/code&gt;.&lt;br&gt;
b. &lt;code&gt;CompletableTask.complete(T value, Executor executor)&lt;/code&gt;&lt;br&gt;
Same as above, but the starting point is a &lt;code&gt;Promise&lt;/code&gt; completed with the specified value:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello!"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myMapper&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myTransformer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;   
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenAcceptAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myConsumer&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenRunAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAction&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;All of &lt;code&gt;myMapper&lt;/code&gt;, &lt;code&gt;myTransformer&lt;/code&gt;, &lt;code&gt;myConsumer&lt;/code&gt;, &lt;code&gt;myAction&lt;/code&gt; will be executed using &lt;code&gt;myExecutor&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Crucially, all composed promises support true cancellation (incl. interrupting thread) for the functions supplied as arguments:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asyncOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myExecutor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myValueGenerator&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenRunAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;myAction&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;cancel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the example above &lt;code&gt;myValueGenerator&lt;/code&gt; will be interrupted if already in progress. Both &lt;code&gt;p2&lt;/code&gt; and &lt;code&gt;p3&lt;/code&gt; will be settled with failure: &lt;code&gt;p2&lt;/code&gt; with a &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CancellationException.html" rel="noopener noreferrer"&gt;CancellationException&lt;/a&gt; and &lt;code&gt;p3&lt;/code&gt; with a &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionException.html" rel="noopener noreferrer"&gt;CompletionException&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You may notice, that above the term "asynchronous composition methods" is used, as well as &lt;code&gt;*Async&lt;/code&gt; calls in examples (like &lt;code&gt;thenApplyAsync&lt;/code&gt;, &lt;code&gt;thenRunAsync&lt;/code&gt;. This is not accidental: non-asynchronous methods of &lt;code&gt;CompletionStage&lt;/code&gt; API are not interruptible. The grounding beneath the design decision is that invoking asynchronous methods involves inevitable overhead of putting command to the queue of the executor, starting new threads implicitly, etc. And for simple, non-blocking methods, like small calculations, trivial transformations and alike this overhead might outweigh method's execution time itself. So the guideline is: use asynchronous composition methods for heavy I/O-bound blocking tasks, and use non-asynchronous composition methods for (typically lightweight) calculations.&lt;/p&gt;

&lt;p&gt;Worth to mention, that &lt;code&gt;CompletableTask&lt;/code&gt;-s and &lt;code&gt;Promise&lt;/code&gt;-s composed out of it may be ever interruptible &lt;em&gt;only&lt;/em&gt; if the &lt;code&gt;Executor&lt;/code&gt; used is interruptible by nature. For example, &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ThreadPoolExecutor.html" rel="noopener noreferrer"&gt;ThreadPoolExecutor&lt;/a&gt; supports interruptible tasks, but &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ForkJoinPool.html" rel="noopener noreferrer"&gt;ForkJoinPool&lt;/a&gt; does not!&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Overriding default asynchronous executor
&lt;/h2&gt;

&lt;p&gt;One of the pitfalls of the &lt;code&gt;CompletableFuture&lt;/code&gt; implementation is how it works with default asynchronous executor. Consider the following example:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;produceValue&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executorInitial&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;transformValueA&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;transformValueB&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executorNext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;transformValueC&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The call to &lt;code&gt;produceValue&lt;/code&gt; will be executed on the &lt;code&gt;executorInitial&lt;/code&gt; - it is passed explicitly. However, the call to &lt;code&gt;transformValueA&lt;/code&gt; will be excuted on... &lt;code&gt;ForkJoinPool.commonPool()&lt;/code&gt;! Hmmmm... Probably this makes sense, but how to force using alternative executor by default? No way! Probably this is possible with deeper calls? The answer is "NO" again! The invocation to &lt;code&gt;transformValueB&lt;/code&gt; ran on explicitly supplied &lt;code&gt;executorNext&lt;/code&gt;. But next call, &lt;code&gt;transformValueC&lt;/code&gt; will be executed on... you guess it... &lt;code&gt;ForkJoinPool.commonPool()&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;So, once you use &lt;code&gt;CompletableFuture&lt;/code&gt; with JEE environment you must pass explicit instance of &lt;a href="https://docs.oracle.com/javaee/7/api/javax/enterprise/concurrent/ManagedExecutorService.html" rel="noopener noreferrer"&gt;ManagedExecutorService&lt;/a&gt; to each and every method call. Not very convenient! To be fair, with Java 9+ API you can redefine this behavior via sub-classing &lt;code&gt;CompletableFuture&lt;/code&gt; and overriding two methods: &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CompletableFuture.html#defaultExecutor--" rel="noopener noreferrer"&gt;defaultExecutor&lt;/a&gt; and &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CompletableFuture.html#newIncompleteFuture--" rel="noopener noreferrer"&gt;newIncompleteFuture&lt;/a&gt;. Plus, you will have to define your own "entry points" instead of the standard &lt;code&gt;CompletableFuture.runAsync&lt;/code&gt; and &lt;code&gt;CompletableFuture.supplyAsync&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;With &lt;code&gt;CompletableTask&lt;/code&gt; the situation is just the opposite. Let us rewrite the example above:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;produceValue&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executorInitial&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p1&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;transformValueA&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p2&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;transformValueB&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executorNext&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p4&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p3&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;transformValueC&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The call to &lt;code&gt;produceValue&lt;/code&gt; will be executed on the &lt;code&gt;executorInitial&lt;/code&gt;, obviously. But now, the call to &lt;code&gt;transformValueA&lt;/code&gt; will be executed also on &lt;code&gt;executorInitial&lt;/code&gt;! What's about deeper calls? The invocation to &lt;code&gt;transformValueB&lt;/code&gt; ran on explicitly supplied &lt;code&gt;executorNext&lt;/code&gt;. And next call, &lt;code&gt;transformValueC&lt;/code&gt; will be executed on... check your intuition... &lt;code&gt;executorNext&lt;/code&gt;. The logic behinds this is the following: the latest explicitly specified &lt;code&gt;Executor&lt;/code&gt; is what will be used for all nested asynchronous composition methods without an explicit &lt;code&gt;Executor&lt;/code&gt; parameter.&lt;/p&gt;

&lt;p&gt;Obviously, it's rarely the case when one size fits all. therefore two additional options exist to specify default asynchronous executor:&lt;br&gt;
A. &lt;code&gt;CompletableTask&lt;/code&gt; has an overloaded method:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Void&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;asyncOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;enforceDefaultAsync&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;When &lt;code&gt;enforceDefaultAsync&lt;/code&gt; is &lt;code&gt;true&lt;/code&gt; then all nested asynchronous composition methods without explicit &lt;code&gt;Executor&lt;/code&gt; parameter will use the provided executor, even if previous composition methods use alternative &lt;code&gt;Executor&lt;/code&gt;. This is somewhat similar to &lt;code&gt;CompletableFuture&lt;/code&gt; but with the ability to explicitly set the default asynchronous executor initially.&lt;br&gt;
B. &lt;code&gt;Promise&lt;/code&gt; interface has the following operation:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;defaultAsyncOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The returned decorator will use the specified executor for all nested asynchronous composition methods without explicit &lt;code&gt;Executor&lt;/code&gt; parameter. So, at any point, you are able to switch to the desired default asynchronous executor and keep using it for all nested composition call.&lt;/p&gt;

&lt;p&gt;To summarize, with Tascalate Concurrent you have the following options to control what is the default asynchronous executor:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The latest explicit &lt;code&gt;Executor&lt;/code&gt; passed to &lt;code&gt;*Async&lt;/code&gt; method is used for derived &lt;code&gt;Promise&lt;/code&gt;-s - the default option.&lt;/li&gt;
&lt;li&gt;Single default &lt;code&gt;Executor&lt;/code&gt; passed to the root &lt;code&gt;CompletableTask.asyncOn(Executor executor, true)&lt;/code&gt; call is propagated through the whole chain. This is the only variant supported with &lt;code&gt;CompletableFuture&lt;/code&gt; in Java 9+, though, with custom coding.&lt;/li&gt;
&lt;li&gt;Redefine &lt;code&gt;Executor&lt;/code&gt; with &lt;code&gt;defaultAsyncOn(Executor executor)&lt;/code&gt; for all derived &lt;code&gt;Promise&lt;/code&gt;-s.
Having the best of three(!) worlds, the only responsibility of the library user is to use these options consistently! 
The last thing that should be mentioned is a typical task when you would like to start interruptible blocking method after completion of the standard &lt;code&gt;CompletableFuture&lt;/code&gt;. The following utility method is defined in the &lt;code&gt;CompletableTask&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;waitFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Roughly, this is a shortcut for the following:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asyncOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;thenCombine&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A typical usage of this method is:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;TaskExecutorService&lt;/span&gt; &lt;span class="n"&gt;executorService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;TaskExecutors&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;newFixedThreadPool&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;replyUrlPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sendRequestAsync&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dataPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;waitFor&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;replyUrlPromise&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executorService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;loadDataInterruptibly&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;dataPromise&lt;/code&gt; returned may be cancelled later and &lt;code&gt;loadDataInterruptibly&lt;/code&gt; will be interrupted if not completed by that time.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. Timeouts
&lt;/h2&gt;

&lt;p&gt;Any robust application must handles situations when things go wrong. An ability to cancel an operation that takes too long existed in the library from the day one. But, the very definition of the "too long" was left to an application code initially. However, the practice shows that a lack of the proven, thoroughly tested timeout-related stuff in the library leads to a complex, repeatative and, unfortunately, error-prone code in application. Hence Tascalate Concurrent was extended to address this omission.&lt;/p&gt;

&lt;p&gt;The library offers the following operations to control execution time of the &lt;code&gt;Promise&lt;/code&gt; (declared in &lt;code&gt;Promise&lt;/code&gt; interface):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelOnTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelOnTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;These methods create a new &lt;code&gt;Promise&lt;/code&gt; that is either settled successfully/exceptionally when original promise is completed within a timeout given; or it is settled exceptionally with a &lt;a href="https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/TimeoutException.html" rel="noopener noreferrer"&gt;TimeoutException&lt;/a&gt; when time expired. In any case, handling code is executed on the default asynchronous &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/Executor.html" rel="noopener noreferrer"&gt;Executor&lt;/a&gt; of the original &lt;code&gt;Promise&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt; &lt;span class="c1"&gt;// Get an executor&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;callPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nextPromiseSync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;callPromise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;whenComplete&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processResultSync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;nextPromiseAsync&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;callPromise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;whenCompleteAsync&lt;/span&gt;&lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;processResultAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the example above &lt;code&gt;callPromise&lt;/code&gt; will be settled within 3 seconds either successfully/exceptionally as a result of the &lt;code&gt;someLongRunningIoBoundMehtod&lt;/code&gt; execution, or exceptionally with a &lt;code&gt;TimeoutException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's worth to mention, that &lt;em&gt;both&lt;/em&gt; &lt;code&gt;processResultSync&lt;/code&gt; and &lt;code&gt;processResultAsync&lt;/code&gt; will be executed with &lt;code&gt;myExecutor&lt;/code&gt;, if timeout is triggered - this rule is true for all timeout-related methods.&lt;/p&gt;

&lt;p&gt;The optional &lt;code&gt;cancelOnTimeout&lt;/code&gt; parameter defines whether or not to cancel the original &lt;code&gt;Promise&lt;/code&gt; when time is expired; it is implicitly true when omitted. So in example above &lt;code&gt;the someLongRunningIoBoundMehtod&lt;/code&gt; will be interrupted if it takes more than 3 seconds to complete. Pay attention: any &lt;code&gt;Promise&lt;/code&gt; is cancellable on timeout, even wrappers created via &lt;code&gt;Promises.from(stage)&lt;/code&gt;, but only &lt;code&gt;CompletableTask&lt;/code&gt; is interruptible!&lt;/p&gt;

&lt;p&gt;Cancelling original promise on timeout is a desired behavior in most cases but not always. In reality, "Warn-first-Cancel-next"  scenarios are not rare, where "warn" may be logging, sending notification emails, showing messages to user on UI etc. The library provides an option to set several non-cancelling timeouts like in the example below:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt; &lt;span class="c1"&gt;// Get an executor&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resultPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Show UI message to user to let him/her know that everything is under control&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resultPromise&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exceptionally&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;TimeoutException&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;UI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;showMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"The operation takes longer than expected, please wait..."&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// Show UI confirmation to user to let him/her cancel operation explicitly&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;t2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resultPromise&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;exceptionally&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;TimeoutException&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;UI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;clearMessages&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="no"&gt;UI&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;showConfirmation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Service does not respond. Do you whant to cancel (Y/N)?"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;},&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// Cancel in 10 seconds&lt;/span&gt;
&lt;span class="n"&gt;resultPromise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Please note that the timeout is started from the call to the &lt;code&gt;orTimeout&lt;/code&gt; method. Hence, if you have a chain of unresolved promises ending with the &lt;code&gt;orTimeout&lt;/code&gt; call then the whole chain should be completed within the time given:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt; &lt;span class="c1"&gt;// Get an executor&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;parallelPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningDbCall&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resultPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;converterMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenCombineAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parallelPromise&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;In the latest example &lt;code&gt;resultPromise&lt;/code&gt; will be resolved successfully if and only if all of &lt;code&gt;someLongRunningIoBoundMehtod&lt;/code&gt;, &lt;code&gt;converterMethod&lt;/code&gt; and even &lt;code&gt;someLongRunningDbCall&lt;/code&gt; are completed within 5 seconds. If it's necessary to restrict execution time of the single step, please use standard &lt;code&gt;CompletionStage.thenCompose&lt;/code&gt; method. Say, that in the previous example we have to restrict execution time of the &lt;code&gt;converterMethod&lt;/code&gt; only. Then the modified chain will look like:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;resultPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// Restict only execution time of converterMethod&lt;/span&gt;
    &lt;span class="c1"&gt;// -- start of changes&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenCompose&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; 
        &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;complete&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
                       &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vv&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;converterMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vv&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
                       &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;// -- end of changes&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenCombineAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;parallelPromise&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Moreover, in the &lt;em&gt;original&lt;/em&gt; example only the call to the &lt;code&gt;thenCombineAsync&lt;/code&gt; will be cancelled on timeout (the last in the chain), to cancel the whole chain it's necessary to use a functionality of the &lt;code&gt;DependentPromise&lt;/code&gt; interface (will be discussed in next post).&lt;/p&gt;

&lt;p&gt;Another useful timeout-related methods declared in &lt;code&gt;Promise&lt;/code&gt; interface are:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelOnTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelOnTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelOnTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;onTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Supplier&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelOnTimeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;onTimeout&lt;/code&gt; family of methods are similar in all regards to the &lt;code&gt;orTimeout&lt;/code&gt; methods with the single obvious difference - instead of completing resulting &lt;code&gt;Promise&lt;/code&gt; exceptionally with the &lt;code&gt;TimeoutException&lt;/code&gt; when time is expired, they are settled successfully with the alternative &lt;code&gt;value&lt;/code&gt; supplied (either directly or via &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html" rel="noopener noreferrer"&gt;Supplier&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt; &lt;span class="c1"&gt;// Get an executor&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;callPromise&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onTimeout&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="s"&gt;"Timed-out!"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The example shows, that &lt;code&gt;callPromise&lt;/code&gt; will be settled within 3 seconds either successfully/exceptionally as a result of the &lt;code&gt;someLongRunningIoBoundMehtod&lt;/code&gt; execution, or with a default value &lt;code&gt;"Timed-out!"&lt;/code&gt; when time exceeded.&lt;/p&gt;

&lt;p&gt;It's important to mention the crucial difference between &lt;code&gt;Promise.orTimeot / onTimeout&lt;/code&gt; and &lt;code&gt;CompletableFuture.orTimeout / completeOnTimeout&lt;/code&gt; in Java 9+. In Tascalate Concurrent both operations return a &lt;em&gt;new&lt;/em&gt; &lt;code&gt;Promise&lt;/code&gt;, that is may be canceled individually, without cancelling the original &lt;code&gt;Promise&lt;/code&gt;. Moreover, the original &lt;code&gt;Promise&lt;/code&gt; will not be completed with &lt;code&gt;TimeoutException&lt;/code&gt; when time expired but rather with the &lt;code&gt;CancellationException&lt;/code&gt; (in the case of &lt;code&gt;orTimeout([duration], true)&lt;/code&gt; or &lt;code&gt;orTimeout([duration])&lt;/code&gt;). The behavior of &lt;code&gt;CompletableFuture&lt;/code&gt; in Java 9+ is radically different: timeout-related operations are just "side-effects", and the returned value is the original &lt;code&gt;CompletableFuture&lt;/code&gt; itself. So the call to &lt;code&gt;completableFuture.orTimeout(100, TimeUnit.MILLIS).cancel()&lt;/code&gt; will cancel the &lt;code&gt;completableFuture&lt;/code&gt; itself, and there is no way to revert the timeout once it's set. Correspondingly, when time expired the original &lt;code&gt;completableFuture&lt;/code&gt; will be completed exceptionally with &lt;code&gt;TimeoutException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code&gt;Promise&lt;/code&gt; interface provides an option to insert delays into the call chain:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;delayOnError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;[,&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;delayOnError&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The delay is started only after the original &lt;code&gt;Promise&lt;/code&gt; is completed either successfully or exceptionally (unlike &lt;code&gt;orTimeout&lt;/code&gt; / &lt;code&gt;onTimeout&lt;/code&gt; methods where timeout is started immediately). The resulting delay &lt;code&gt;Promise&lt;/code&gt; is resolved after the timeout specified with the same result as the original &lt;code&gt;Promise&lt;/code&gt;. The latest methods' argument - &lt;code&gt;delayOnError&lt;/code&gt; - specifies whether or not we should delay if original Promise is resolved exceptionally, by default this argument is &lt;code&gt;true&lt;/code&gt;. If &lt;code&gt;false&lt;/code&gt;, then delay &lt;code&gt;Promise&lt;/code&gt; is completed immediately after the failed original &lt;code&gt;Promise&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;myExecutor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...;&lt;/span&gt; &lt;span class="c1"&gt;// Get an executor&lt;/span&gt;
&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;callPromise1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;someLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Give a second for CPU to calm down :)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;convertValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;callPromise2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;CompletableTask&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;supplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;aletrnativeLongRunningIoBoundMehtod&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Give a second for CPU to calm down ONLY on success :)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApply&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;convertValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Like with other timeout-related methods, &lt;code&gt;convertValue&lt;/code&gt; is invoked on the default asynchronous &lt;code&gt;Executor&lt;/code&gt; of the original &lt;code&gt;Promise&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;You may notice, that delay may be introduced only in the middle of the chain, but what to do if you'd like to back-off the whole chain execution? Just start with a resolved promise!&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Option 1&lt;/span&gt;
&lt;span class="c1"&gt;// Interruptible tasks chain on the executor supplied&lt;/span&gt;
&lt;span class="nc"&gt;CompletableTask&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asyncOn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;produceValue&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;span class="c1"&gt;// Option2&lt;/span&gt;
&lt;span class="c1"&gt;// Computational tasks on ForkJoinPool.commonPool()&lt;/span&gt;
&lt;span class="nc"&gt;Promises&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CompletableFuture&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;completedFuture&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofSeconds&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;thenApplyAsync&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ignore&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;produceValue&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As long as back-off execution is not a very rare case, the library provides the following convenient shortcuts in the &lt;code&gt;CompletableTask&lt;/code&gt; class:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TimeUnit&lt;/span&gt; &lt;span class="n"&gt;unit&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Duration&lt;/span&gt; &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Executor&lt;/span&gt; &lt;span class="n"&gt;executor&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Notice, that in Java 9+ a different approach is chosen to implement delays - there is no corresponding operation defined for the &lt;code&gt;CompletableFuture&lt;/code&gt; object and you should use delayed &lt;code&gt;Executor&lt;/code&gt;. Please read documentation on the &lt;a href="https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/CompletableFuture.html#delayedExecutor-long-java.util.concurrent.TimeUnit-java.util.concurrent.Executor-" rel="noopener noreferrer"&gt;CompletableFuture.delayedExecutor&lt;/a&gt; method for details.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Combining several CompletionStage-s.
&lt;/h2&gt;

&lt;p&gt;The utility class &lt;code&gt;Promises&lt;/code&gt; provides a rich set of methods to combine several &lt;code&gt;CompletionStage&lt;/code&gt;-s, that lefts limited functionality of &lt;code&gt;CompletableFuter.allOf / anyOf&lt;/code&gt; far behind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The library works with any &lt;code&gt;CompletionStage&lt;/code&gt; implementation without resorting to converting arguments to &lt;code&gt;CompletableFuture&lt;/code&gt; first (and &lt;code&gt;CompletionStage.toCompletableFuture&lt;/code&gt; is an optional operation, at least it's documented so in Java 8).&lt;/li&gt;
&lt;li&gt;It's possible to pass either an array or a &lt;code&gt;List&lt;/code&gt; of &lt;code&gt;CompletionStage&lt;/code&gt;-s as arguments.&lt;/li&gt;
&lt;li&gt;The resulting &lt;code&gt;Promise&lt;/code&gt; let access individual results of the settled &lt;code&gt;CompletionStage&lt;/code&gt;-s passed.&lt;/li&gt;
&lt;li&gt;There is an option to cancel non-settled &lt;code&gt;CompletionStage&lt;/code&gt;-s passed once the result of the operation is known.&lt;/li&gt;
&lt;li&gt;Optionally you can specify whether or not to tolerate individual failures as long as they don't affect the final result.&lt;/li&gt;
&lt;li&gt;General &lt;em&gt;M completed successfully out of N passed promises&lt;/em&gt; scenario is possible.
Let us review the relevant methods, from the simplest ones to the most advance.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                 &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Returns a promise that is completed normally when all &lt;code&gt;CompletionStage&lt;/code&gt;-s passed as parameters are completed normally; if any promise completed exceptionally, then resulting promise is completed exceptionally as well.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                          &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;any&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                          &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Returns a promise that is completed normally when any &lt;code&gt;CompletionStage&lt;/code&gt; passed as parameters is completed normally (race is possible); if all promises completed exceptionally, then resulting promise is completed exceptionally as well.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;anyStrict&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;anyStrict&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Returns a promise that is completed normally when any &lt;code&gt;CompletionStage&lt;/code&gt; passed as parameters is completed normally (race is possible); if any promise completed exceptionally before the first result is available, then resulting promise is completed exceptionally as well (unlike non-Strict variant, where exceptions are ignored if any result is available at all).&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;atLeast&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minResultsCount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                    &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;atLeast&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minResultsCount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                    &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generalization of the &lt;code&gt;any&lt;/code&gt; method. Returns a promise that is completed normally when at least &lt;code&gt;minResultCount&lt;/code&gt;&lt;br&gt;
of &lt;code&gt;CompletionStage&lt;/code&gt;-s passed as parameters are completed normally (race is possible); if less than &lt;code&gt;minResultCount&lt;/code&gt; of promises completed normally, then resulting promise is completed exceptionally.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;atLeastStrict&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minResultsCount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                          &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;...&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;atLeastStrict&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;minResultsCount&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="n"&gt;cancelRemaining&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;,]&lt;/span&gt; 
                                          &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;CompletionStage&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;promises&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Generalization of the &lt;code&gt;anyStrict&lt;/code&gt; method. Returns a promise that is completed normally when at least &lt;code&gt;minResultCount&lt;/code&gt; of &lt;code&gt;CompletionStage&lt;/code&gt;-s passed as parameters are completed normally (race is possible); if any promise completed exceptionally before &lt;code&gt;minResultCount&lt;/code&gt; of results are available, then resulting promise is completed exceptionally as well (unlike non-Strict variant, where exceptions are ignored if &lt;code&gt;minResultsCount&lt;/code&gt; of successful results are available).&lt;/p&gt;

&lt;p&gt;All methods above have an optional parameter &lt;code&gt;cancelRemaining&lt;/code&gt;. When omitted, it means implicitly &lt;code&gt;cancelRemaining = true&lt;/code&gt;. The &lt;code&gt;cancelRemaining&lt;/code&gt; parameter defines whether or not to eagerly cancel remaining &lt;code&gt;promises&lt;/code&gt; once the result of the operation is known, i.e. enough &lt;code&gt;promises&lt;/code&gt; passed are settled successfully &lt;em&gt;or&lt;/em&gt; some &lt;code&gt;CompletionStage&lt;/code&gt; completed exceptionally in strict version. &lt;/p&gt;

&lt;p&gt;Each operation to combine &lt;code&gt;CompletionStage&lt;/code&gt;-s has overloaded versions that accept either a &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/List.html" rel="noopener noreferrer"&gt;List&lt;/a&gt; of &lt;code&gt;CompletionStage&lt;/code&gt;-s or varagr array of &lt;code&gt;CompletionStage&lt;/code&gt;-s.&lt;/p&gt;

&lt;p&gt;Besides &lt;code&gt;any&lt;/code&gt;/&lt;code&gt;anyStrict&lt;/code&gt; methods that return single-valued promise, all other combining methods return a list of values per every successfully completed promise, at the same indexed position. If the promise at the given position was not settled at all, or failed (in non-strict version), then corresponding item in the result list is &lt;code&gt;null&lt;/code&gt;. If necessary number or &lt;code&gt;promises&lt;/code&gt; was not completed successfully, or any one completed exceptionally in strict version, then resulting &lt;code&gt;Promise&lt;/code&gt; is settled with a failure of the type &lt;code&gt;MultitargetException&lt;/code&gt;. Application developer may examine &lt;code&gt;MultitargetException.getExceptions()&lt;/code&gt; to check what is the exact failure per concrete &lt;code&gt;CompletionStage&lt;/code&gt; passed.&lt;br&gt;
The &lt;code&gt;Promise&lt;/code&gt; returned has the following characteristics:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cancelling resulting &lt;code&gt;Promise&lt;/code&gt; will cancel all the &lt;code&gt;CompletionStage-s&lt;/code&gt; passed as arguments.&lt;/li&gt;
&lt;li&gt;Default asynchronous executor of the resulting &lt;code&gt;Promise&lt;/code&gt; is undefined, i.e. it could be either &lt;code&gt;ForkJoin.commonPool&lt;/code&gt; or whatever &lt;code&gt;Executor&lt;/code&gt; is used by any of the &lt;code&gt;CompletionStage&lt;/code&gt; passed as argument. To ensure that necessary default &lt;code&gt;Executor&lt;/code&gt; is used for subsequent asynchronous operations, please apply &lt;code&gt;defaultAsyncOn(myExecutor)&lt;/code&gt; on the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The list of features provided by the Tascalate Concurrent library doesn't stop here. There is more interesting stuff like Retry / Poll functionality, controlling cancellation of the chain of &lt;code&gt;Promises&lt;/code&gt;, extensions to &lt;code&gt;ExecutorService&lt;/code&gt; etc. But this post is already getting too long, so the reamaing is left for the next time. In the meantime, you can check the home page of the &lt;a href="https://github.com/vsilaev/tascalate-concurrent" rel="noopener noreferrer"&gt;Tascalate Concurrent&lt;/a&gt; library for the most up-to-date documentation.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/vsilaev" rel="noopener noreferrer"&gt;
        vsilaev
      &lt;/a&gt; / &lt;a href="https://github.com/vsilaev/tascalate-concurrent" rel="noopener noreferrer"&gt;
        tascalate-concurrent
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Implementation of blocking (IO-Bound) cancellable java.util.concurrent.CompletionStage and related extensions to java.util.concurrent.ExecutorService-s
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a href="https://search.maven.org/artifact/net.tascalate/net.tascalate.concurrent/0.9.8/jar" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/218c57924c7d351f6dadb11cac4eaa6809eb848b9a75ae03b557bc6a13899117/68747470733a2f2f696d672e736869656c64732e696f2f6d6176656e2d63656e7472616c2f762f6e65742e74617363616c6174652f6e65742e74617363616c6174652e636f6e63757272656e742e737667" alt="Maven Central"&gt;&lt;/a&gt; &lt;a href="https://github.com/vsilaev/tascalate-concurrent/releases/tag/0.9.8" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c071118d282dab0cf12ce0385fa3990cf0b3b5c635792e2cb6377fb9683bf621/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f7673696c6165762f74617363616c6174652d636f6e63757272656e742e737667" alt="GitHub release"&gt;&lt;/a&gt; &lt;a href="http://www.apache.org/licenses/LICENSE-2.0.txt" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/c9340043fe51dd289d3cffeeddad0ae78d1702d0b7f4c65eefc7cec343467ce1/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f7673696c6165762f74617363616c6174652d636f6e63757272656e742e737667" alt="license"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;tascalate-concurrent&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;The library provides an implementation of the &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletionStage.html" rel="nofollow noopener noreferrer"&gt;CompletionStage&lt;/a&gt; interface and related classes these are designed to support long-running blocking tasks (typically, I/O bound). This functionality augments the sole Java 8 built-in implementation, &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="nofollow noopener noreferrer"&gt;CompletableFuture&lt;/a&gt;, that is primarily supports computational tasks. Also, the library helps with numerous asynchronous programing challenges like handling timeouts, retry/poll functionality, orchestrating results of multiple concurrent computations and similar.&lt;/p&gt;

&lt;p&gt;Since the version &lt;a href="https://github.com/vsilaev/tascalate-concurrent/releases/tag/0.7.0" rel="noopener noreferrer"&gt;0.7.0&lt;/a&gt; the library is shipped as a multi-release JAR and may be used both with Java 8 as a classpath library or with Java 9+ as a module.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;IMPORTANT!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the version &lt;a href="https://github.com/vsilaev/tascalate-concurrent/releases/tag/0.8.0" rel="noopener noreferrer"&gt;0.8.0&lt;/a&gt; the artifact was renamed
New name:&lt;/p&gt;
&lt;div class="highlight highlight-text-xml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&amp;lt;&lt;span class="pl-ent"&gt;dependency&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span class="pl-ent"&gt;groupId&lt;/span&gt;&amp;gt;net.tascalate&amp;lt;/&lt;span class="pl-ent"&gt;groupId&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span class="pl-ent"&gt;artifactId&lt;/span&gt;&amp;gt;net.tascalate.concurrent&amp;lt;/&lt;span class="pl-ent"&gt;artifactId&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span class="pl-ent"&gt;version&lt;/span&gt;&amp;gt;0.9.8&amp;lt;/&lt;span class="pl-ent"&gt;version&lt;/span&gt;&amp;gt; &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;&amp;lt;!--&lt;/span&gt; Any version above 0.8.0, the latest one is recommended &lt;span class="pl-c"&gt;--&amp;gt;&lt;/span&gt;&lt;/span&gt;
&amp;lt;/&lt;span class="pl-ent"&gt;dependency&lt;/span&gt;&amp;gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Old Name&lt;/p&gt;
&lt;div class="highlight highlight-text-xml notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&amp;lt;&lt;span class="pl-ent"&gt;dependency&lt;/span&gt;&amp;amp;gt
    &amp;lt;&lt;span class="pl-ent"&gt;groupId&lt;/span&gt;&amp;gt;net.tascalate.concurrent&amp;lt;/&lt;span class="pl-ent"&gt;groupId&lt;/span&gt;&amp;gt;
    &amp;lt;&lt;span class="pl-ent"&gt;artifactId&lt;/span&gt;&amp;gt;net.tascalate.concurrent.lib&amp;lt;/&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/vsilaev/tascalate-concurrent" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;h1&gt;
  
  
  Acknowledgements
&lt;/h1&gt;

&lt;p&gt;Internal implementation details of the &lt;code&gt;CompletableTask&lt;/code&gt; class hierarchy are greatly inspired &lt;a href="https://github.com/lukas-krecan/completion-stage" rel="noopener noreferrer"&gt;by the work&lt;/a&gt; done by &lt;a href="https://github.com/lukas-krecan" rel="noopener noreferrer"&gt;Lukáš Křečan&lt;/a&gt;. A description of his library is available as a two-part article on DZone: &lt;a href="https://dzone.com/articles/implementing-java-8" rel="noopener noreferrer"&gt;Part 1&lt;/a&gt; and &lt;a href="https://dzone.com/articles/implementing-java-8-0" rel="noopener noreferrer"&gt;Part II&lt;/a&gt;. It's a worth reading for those, who'd like to have better understanding of the &lt;code&gt;CompletableTask&lt;/code&gt; internals.&lt;/p&gt;

</description>
      <category>java</category>
      <category>opensource</category>
      <category>programming</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
