CircuitBreaker.java

package net.secodo.jcircuitbreaker.breaker;

import java.util.concurrent.Callable;
import net.secodo.jcircuitbreaker.breaker.execution.ExecutionContext;
import net.secodo.jcircuitbreaker.breakhandler.BreakHandler;
import net.secodo.jcircuitbreaker.breakhandler.exception.BreakHandlerException;
import net.secodo.jcircuitbreaker.breakstrategy.BreakStrategy;
import net.secodo.jcircuitbreaker.exception.CircuitBreakerException;
import net.secodo.jcircuitbreaker.exception.TaskExecutionException;
import net.secodo.jcircuitbreaker.task.Task;


/**
 * This interface defines the circuit breaker contract.
 *
 * <p>For details refer to comments on methods.
 *
 * @param <R> the return value that the breaker returns (if breaker wants to return any value)
 */
public interface CircuitBreaker<R> {
  /**
   * Executes the given {@link Callable} only when given {@link BreakStrategy} allows the execution at the time of call.
   * If execution is not allowed {@link BreakHandler} is used to handle this situation and return fallback value.
   *
   * @param task          encapsulates java method to be executed - called <i>target-method</i> in this context
   * @param breakStrategy decides whether to execute the task or prevent execution and executed breakHandler instead
   * @param breakHandler  handles the situation when the strategy does not allow method execution
   * @return the return value of the executed task or the fallback value returned by breakHandler in case of
   *         execution of method did not take place
   * @throws TaskExecutionException if execution of task resulted in exception
   * @throws BreakHandlerException   if breakHandler (if executed) could not provide the fallback value
   * @throws CircuitBreakerException if unexpected problem occurred while processing the task within CircuitBreaker
   */
  default R execute(Task<R> task, BreakStrategy<R> breakStrategy, BreakHandler<R> breakHandler)
             throws TaskExecutionException, BreakHandlerException, CircuitBreakerException {
    return execute(task, breakStrategy, breakHandler, null);
  }


  /**
   * Executes the given {@link Callable} only when given {@link BreakStrategy} allows the execution at the time of call.
   * If execution is not allowed {@link BreakHandler} is used to handle this situation and return fallback value.
   * <p>
   * Allows to pass some custom data to the strategy which will be available via {@link ExecutionContext#getUserData()}
   *
   * @param task          encapsulates java method to be executed - called <i>target-method</i> in this context
   * @param breakStrategy decides whether to execute the task or prevent execution and executed breakHandler instead
   * @param breakHandler  handles the situation when the strategy does not allow method execution
   * @param userData      custom user data which will be available to strategies via
   *                      {@link ExecutionContext#getUserData()}
   * @param <U>           the type of user data passed to execution context
   * @return the return value of the executed task or the fallback value returned by breakHandler in case of
   * execution of method did not take place
   * @throws TaskExecutionException if execution of task resulted in exception
   * @throws BreakHandlerException   if breakHandler (if executed) could not provide the fallbackvalue
   * @throws CircuitBreakerException if the method execution resulted in exception or breakHandler resulted in exception
   */
  <U> R execute(Task<R> task, BreakStrategy<R> breakStrategy, BreakHandler<R> breakHandler,
                U userData) throws TaskExecutionException, BreakHandlerException, CircuitBreakerException;

}