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

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

The newest version!
package com.fitbur.failsafe;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.fitbur.failsafe.Callables.AsyncCallableWrapper;
import com.fitbur.failsafe.function.AsyncCallable;
import com.fitbur.failsafe.function.AsyncRunnable;
import com.fitbur.failsafe.function.CheckedRunnable;
import com.fitbur.failsafe.function.ContextualCallable;
import com.fitbur.failsafe.function.ContextualRunnable;
import com.fitbur.failsafe.internal.util.Assert;
import com.fitbur.failsafe.util.concurrent.Scheduler;

/**
 * Performs asynchronous executions according to a {@link RetryPolicy} and {@link CircuitBreaker}.
 * 
 * @author Jonathan Halterman
 * @param  listener result type
 */
public class AsyncFailsafe extends AsyncListenerBindings, L> {
  private RetryPolicy retryPolicy;
  private CircuitBreaker circuitBreaker;

  AsyncFailsafe(SyncFailsafe failsafe, Scheduler scheduler) {
    super(scheduler);
    this.retryPolicy = failsafe.retryPolicy;
    this.circuitBreaker = failsafe.circuitBreaker;
    this.listeners = failsafe.listeners;
    this.listenerConfig = failsafe.listenerConfig;
  }

  /**
   * Executes the {@code callable} asynchronously until a successful result is returned or the configured
   * {@link RetryPolicy} is exceeded.
   * 
   * @throws NullPointerException if the {@code callable} is null
   * @throws CircuitBreakerOpenException if a configured circuit breaker is open
   */
  public  FailsafeFuture get(Callable callable) {
    return call(Callables.asyncOf(callable), null);
  }

  /**
   * Executes the {@code callable} asynchronously until a successful result is returned or the configured
   * {@link RetryPolicy} is exceeded.
   * 
   * @throws NullPointerException if the {@code callable} is null
   * @throws CircuitBreakerOpenException if a configured circuit breaker is open
   */
  public  FailsafeFuture get(ContextualCallable callable) {
    return call(Callables.asyncOf(callable), null);
  }

  /**
   * Executes the {@code callable} asynchronously until a successful result is returned or the configured
   * {@link RetryPolicy} is exceeded. This method is intended for integration with asynchronous code. Retries must be
   * manually scheduled via one of the {@code AsyncExecution.retry} methods.
   * 
   * @throws NullPointerException if the {@code callable} is null
   * @throws CircuitBreakerOpenException if a configured circuit breaker is open
   */
  public  FailsafeFuture getAsync(AsyncCallable callable) {
    return call(Callables.asyncOf(callable), null);
  }

  /**
   * Executes the {@code runnable} asynchronously until successful or until the configured {@link RetryPolicy} is
   * exceeded.
   * 
   * @throws NullPointerException if the {@code runnable} is null
   * @throws CircuitBreakerOpenException if a configured circuit breaker is open
   */
  public FailsafeFuture run(CheckedRunnable runnable) {
    return call(Callables.asyncOf(runnable), null);
  }

  /**
   * Executes the {@code runnable} asynchronously until successful or until the configured {@link RetryPolicy} is
   * exceeded.
   * 
   * @throws NullPointerException if the {@code runnable} is null
   * @throws CircuitBreakerOpenException if a configured circuit breaker is open
   */
  public FailsafeFuture run(ContextualRunnable runnable) {
    return call(Callables.asyncOf(runnable), null);
  }

  /**
   * Executes the {@code runnable} asynchronously until successful or until the configured {@link RetryPolicy} is
   * exceeded. This method is intended for integration with asynchronous code. Retries must be manually scheduled via
   * one of the {@code AsyncExecution.retry} methods.
   * 
   * @throws NullPointerException if the {@code runnable} is null
   * @throws CircuitBreakerOpenException if a configured circuit breaker is open
   */
  public FailsafeFuture runAsync(AsyncRunnable runnable) {
    return call(Callables.asyncOf(runnable), null);
  }

  /**
   * Executes the {@code callable} asynchronously until the resulting future is successfully completed or the configured
   * {@link RetryPolicy} is exceeded.
   * 

* Supported on Java 8 and above. * * @throws NullPointerException if the {@code callable} is null * @throws CircuitBreakerOpenException if a configured circuit breaker is open */ public java.util.concurrent.CompletableFuture future( Callable> callable) { java.util.concurrent.CompletableFuture response = new java.util.concurrent.CompletableFuture(); call(Callables.ofFuture(callable), new FailsafeFuture(response)); return response; } /** * Executes the {@code callable} asynchronously until the resulting future is successfully completed or the configured * {@link RetryPolicy} is exceeded. *

* Supported on Java 8 and above. * * @throws NullPointerException if the {@code callable} is null * @throws CircuitBreakerOpenException if a configured circuit breaker is open */ public java.util.concurrent.CompletableFuture future( ContextualCallable> callable) { java.util.concurrent.CompletableFuture response = new java.util.concurrent.CompletableFuture(); call(Callables.ofFuture(callable), new FailsafeFuture(response)); return response; } /** * Executes the {@code callable} asynchronously until the resulting future is successfully completed or the configured * {@link RetryPolicy} is exceeded. This method is intended for integration with asynchronous code. Retries must be * manually scheduled via one of the {@code AsyncExecution.retry} methods. *

* Supported on Java 8 and above. * * @throws NullPointerException if the {@code callable} is null * @throws CircuitBreakerOpenException if a configured circuit breaker is open */ public java.util.concurrent.CompletableFuture futureAsync( AsyncCallable> callable) { java.util.concurrent.CompletableFuture response = new java.util.concurrent.CompletableFuture(); call(Callables.ofFuture(callable), new FailsafeFuture(response)); return response; } /** * Configures the {@code circuitBreaker} to be used to control the rate of event execution. * * @throws NullPointerException if {@code circuitBreaker} is null * @throws IllegalStateException if a circuit breaker is already configured */ public AsyncFailsafe with(CircuitBreaker circuitBreaker) { Assert.state(this.circuitBreaker == null, "A circuit breaker has already been configurd"); this.circuitBreaker = Assert.notNull(circuitBreaker, "circuitBreaker"); return this; } /** * Configures the {@code retryPolicy} to be used for retrying failed executions. * * @throws NullPointerException if {@code retryPolicy} is null * @throws IllegalStateException if a retry policy is already configured */ public AsyncFailsafe with(RetryPolicy retryPolicy) { Assert.state(this.retryPolicy == RetryPolicy.NEVER, "A retry policy has already been configurd"); this.retryPolicy = Assert.notNull(retryPolicy, "retryPolicy"); return this; } /** * Configures the {@code listeners} to be called as execution events occur. * * @throws NullPointerException if {@code listeners} is null */ @SuppressWarnings("unchecked") public AsyncFailsafe with(Listeners listeners) { this.listeners = (Listeners) Assert.notNull(listeners, "listeners"); return (AsyncFailsafe) this; } /** * Calls the asynchronous {@code callable} via the {@code executor}, performing retries according to the * {@code retryPolicy}. * * @throws NullPointerException if any argument is null * @throws CircuitBreakerOpenException if a configured circuit breaker is open */ @SuppressWarnings("unchecked") private FailsafeFuture call(AsyncCallableWrapper callable, FailsafeFuture future) { if (circuitBreaker != null) { circuitBreaker.initialize(); if (!circuitBreaker.allowsExecution()) throw new CircuitBreakerOpenException(); } if (future == null) future = new FailsafeFuture(); AsyncExecution execution = new AsyncExecution(callable, retryPolicy, circuitBreaker, scheduler, future, (ListenerBindings) this); callable.inject(execution); try { future.setFuture((Future) scheduler.schedule(callable, 0, TimeUnit.MILLISECONDS)); } catch (Throwable t) { complete(null, t, execution, false); future.complete(null, t); } return future; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy