All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.fitbur.failsafe.FailsafeFuture Maven / Gradle / Ivy

The newest version!
package com.fitbur.failsafe;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import com.fitbur.failsafe.internal.util.Assert;
import com.fitbur.failsafe.internal.util.ReentrantCircuit;

/**
 * The future result of an asynchronous Failsafe execution.
 * 
 * @author Jonathan Halterman
 * @param  result type
 */
public class FailsafeFuture implements Future {
  private final ReentrantCircuit circuit = new ReentrantCircuit();
  private final java.util.concurrent.CompletableFuture completableFuture;

  // Mutable state
  private volatile Future delegate;
  private volatile boolean done;
  private volatile boolean cancelled;
  private volatile T result;
  private volatile Throwable failure;

  FailsafeFuture() {
    this.completableFuture = null;
    circuit.open();
  }

  FailsafeFuture(java.util.concurrent.CompletableFuture future) {
    this.completableFuture = future;
    circuit.open();
  }

  @Override
  public synchronized boolean cancel(boolean mayInterruptIfRunning) {
    boolean result = delegate.cancel(mayInterruptIfRunning);
    cancelled = true;
    circuit.close();
    return result;
  }

  @Override
  public T get() throws InterruptedException, ExecutionException {
    circuit.await();
    if (failure != null)
      throw new ExecutionException(failure);
    return result;
  }

  /**
   * @throws NullPointerException if {@code unit} is null
   * @throws IllegalArgumentException if {@code timeout} is < 0
   */
  @Override
  public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
    Assert.isTrue(timeout >= 0, "timeout cannot be negative");
    if (!circuit.await(timeout, Assert.notNull(unit, "unit")))
      throw new TimeoutException();
    if (failure != null)
      throw new ExecutionException(failure);
    return result;
  }

  @Override
  public boolean isCancelled() {
    return cancelled;
  }

  @Override
  public boolean isDone() {
    return done;
  }

  synchronized void complete(T result, Throwable failure) {
    this.result = result;
    this.failure = failure;
    done = true;

    if (completableFuture != null)
      completeFuture();

    circuit.close();
  }

  void setFuture(Future delegate) {
    this.delegate = delegate;
  }

  private void completeFuture() {
    if (failure == null)
      completableFuture.complete(result);
    else
      completableFuture.completeExceptionally(failure);
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy