title: CompletableFuture with elapsed time information
body: <p>I need to have access to information about asynchronouos method execution time. So, I'm trying to extend <a href="https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html" rel="nofollow">CompletableFuture</a> functionality. Here is my implementation with <a href="https://en.wikipedia.org/wiki/Decorator_pattern#Java" rel="nofollow">decorator</a> pattern usage:</p>
  
  <pre><code>import java.util.concurrent.*;
  import java.util.function.*;
  import static lombok.AccessLevel.PRIVATE;
  import lombok.AllArgsConstructor;
  import lombok.experimental.Delegate;
  
  @AllArgsConstructor(access = PRIVATE)
  public class ContinuousCompletableFuture&lt;T&gt; extends CompletableFuture&lt;T&gt; {
  
      @Delegate
      private final CompletableFuture&lt;T&gt; baseFuture;
  
      private final long creationTime;
  
      public static &lt;U&gt; ContinuousCompletableFuture&lt;U&gt; supplyAsync(Supplier&lt;U&gt; supplier) {
          return new ContinuousCompletableFuture&lt;&gt;(CompletableFuture.supplyAsync(supplier));
      }
  
      private ContinuousCompletableFuture(CompletableFuture&lt;T&gt; baseFuture) {
          this.baseFuture = baseFuture;
          this.creationTime = System.nanoTime();
      }
  
      public Long getElapsedTime() {
          return (System.nanoTime() - creationTime) / 1000_000L;
      }
  
      public ContinuousCompletableFuture&lt;Void&gt; thenAcceptAsync(BiConsumer&lt;? super T, Long&gt; action) {
          CompletionStage&lt;Long&gt; elapsedTime = CompletableFuture.completedFuture(getElapsedTime());
          return new ContinuousCompletableFuture&lt;&gt;(baseFuture.thenAcceptBothAsync(elapsedTime, action), creationTime);
      }
  }
  </code></pre>
  
  <p>First test <code>shouldReturnElapsedTime</code> with extracted <code>ContinuousCompletableFuture</code> variable works fine, but other <code>shouldOperateWithOwnExecutionTime</code> fails. Meanwhile, I prefer to see it in my future code neither extracted <code>ContinuousCompletableFuture</code> variable.</p>
  
  <pre><code>import java.util.concurrent.atomic.AtomicLong;
  import lombok.extern.slf4j.Slf4j;
  import org.junit.*;
  import static org.junit.Assert.*;
  
  @Slf4j
  public class ContinuousCompletableFutureTest {
  
      private static final int DELAY = 1000;
  
      AtomicLong flag = new AtomicLong();
  
      ContinuousCompletableFuture&lt;String&gt; future;
  
      @Before
      public void before() {
          future = ContinuousCompletableFuture.supplyAsync(() -&gt; {
              try {
                  Thread.sleep(DELAY);
              } catch (InterruptedException ex) {
                  log.error("Error during ContinuousCompletableFuture execution", ex);
              }
              return "successfully completed";
          });
      }
  
      @Test
      public void shouldReturnElapsedTime() {
          future.thenAcceptAsync(s -&gt; {
              long t = future.getElapsedTime();
              log.info("Elapsed {} ms to receive message \"{}\"", t, s);
              flag.set(t);
          });
  
          try {
              Thread.sleep(2000);
          } catch (InterruptedException ex) {
              log.error("Error awaiting Test completion", ex);
          }
  
          assertTrue("Future completion should be delayed", flag.get() &gt;= 0.75 * DELAY);
      }
  
      @Test
      public void shouldOperateWithOwnExecutionTime() {
          future.thenAcceptAsync((s, t) -&gt; {
              log.info("Elapsed {} ms to receive message \"{}\"", t, s);
              flag.set(t);
          });
  
          try {
              Thread.sleep(2000);
          } catch (InterruptedException ex) {
              log.error("Error awaiting Test completion", ex);
          }
  
          assertTrue("Future completion should be delayed", flag.get() &gt;= 0.75 * DELAY);
      }
  }
  </code></pre>
  
  <p>I assume that my issue lies in wrong <code>thenAcceptBothAsync</code> method usage. </p>
  
  <p>Any suggestions? </p>