dev.failsafe.CircuitBreaker Maven / Gradle / Ivy
/*
* Copyright 2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package dev.failsafe;
import java.time.Duration;
/**
* A circuit breaker temporarily blocks execution when a configured number of failures are exceeded.
*
* Circuit breakers have three states: closed, open, and half-open. When a circuit breaker is in
* the closed (initial) state, executions are allowed. If a {@link CircuitBreakerBuilder#withFailureThreshold(int)
* configurable number} of failures occur, optionally over some {@link CircuitBreakerBuilder#withFailureThreshold(int,
* Duration) time period}, the circuit breaker transitions to the open state. In the open state a circuit
* breaker will fail executions with {@link CircuitBreakerOpenException}. After a {@link
* CircuitBreakerBuilder#withDelay(Duration) configurable delay}, the circuit breaker will transition to a
* half-open state. In the
* half-open state a {@link CircuitBreakerBuilder#withSuccessThreshold(int) configurable number} of trial
* executions will be allowed, after which the circuit breaker will transition back to closed or open
* depending on how many were successful.
*
*
* A circuit breaker can be count based or time based:
*
* - Count based circuit breakers will transition between states when recent execution results exceed a threshold.
* - Time based circuit breakers will transition between states when recent execution results exceed a threshold
* within a time period.
*
*
* A minimum number of executions must be performed in order for a state transition to occur. Time based circuit
* breakers use a sliding window to aggregate execution results. The window is divided into {@code 10} time slices,
* each representing 1/10th of the {@link CircuitBreakerConfig#getFailureThresholdingPeriod() failureThresholdingPeriod}.
* As time progresses, statistics for old time slices are gradually discarded, which smoothes the calculation of
* success and failure rates.
*
* This class is threadsafe.
*
*
* @param result type
* @author Jonathan Halterman
* @see CircuitBreakerConfig
* @see CircuitBreakerBuilder
* @see CircuitBreakerOpenException
*/
public interface CircuitBreaker extends Policy {
/**
* Creates a CircuitBreakerBuilder that by default will build a count based circuit breaker that opens after a {@link
* CircuitBreakerBuilder#withFailureThreshold(int) single failure}, closes after a {@link
* CircuitBreakerBuilder#withSuccessThreshold(int) single success}, and has a 1 minute {@link
* CircuitBreakerBuilder#withDelay(Duration) delay}, unless configured otherwise.
*/
static CircuitBreakerBuilder builder() {
return new CircuitBreakerBuilder<>();
}
/**
* Creates a count based CircuitBreaker that opens after a {@link CircuitBreakerBuilder#withFailureThreshold(int)
* single failure}, closes after a {@link CircuitBreakerBuilder#withSuccessThreshold(int) single success}, and has a 1
* minute {@link CircuitBreakerBuilder#withDelay(Duration) delay} by default.
*/
static CircuitBreaker ofDefaults() {
return CircuitBreaker.builder().build();
}
/**
* The state of the circuit.
*/
enum State {
/** The circuit is closed and fully functional, allowing executions to occur. */
CLOSED,
/** The circuit is opened and not allowing executions to occur. */
OPEN,
/** The circuit is temporarily allowing executions to occur. */
HALF_OPEN
}
/**
* Returns the {@link CircuitBreakerConfig} that the CircuitBreaker was built with.
*/
CircuitBreakerConfig getConfig();
/**
* Attempts to acquire a permit for the circuit breaker and throws {@link CircuitBreakerOpenException} if a permit
* could not be acquired. Permission will be automatically released when a result or failure is recorded.
*
* @throws CircuitBreakerOpenException Thrown when the circuit breaker is in a half-open state and no permits remain
* according to the configured success or failure thresholding capacity.
* @see #recordResult(Object)
* @see #recordFailure(Throwable)
* @see #recordSuccess()
* @see #recordFailure()
*/
void acquirePermit();
/**
* Attempts to acquire a permit to use the circuit breaker and returns whether a permit was acquired. Permission will
* be automatically released when a result or failure is recorded.
*
* @see #recordResult(Object)
* @see #recordFailure(Throwable)
* @see #recordSuccess()
* @see #recordFailure()
*/
boolean tryAcquirePermit();
/**
* Opens the circuit.
*/
void open();
/**
* Closes the circuit.
*/
void close();
/**
* Half-opens the circuit.
*/
void halfOpen();
/**
* Gets the state of the circuit.
*/
State getState();
/**
* Returns the number of executions recorded in the current state when the state is CLOSED or HALF_OPEN. When the
* state is OPEN, returns the executions recorded during the previous CLOSED state.
*
* For count based thresholding, the max number of executions is limited to the execution threshold. For time based
* thresholds, the number of executions may vary within the thresholding period.
*
*/
int getExecutionCount();
/**
* When in the OPEN state, returns the remaining delay until the circuit is half-opened and allows another execution,
* else returns {@code Duration.ZERO}.
*/
Duration getRemainingDelay();
/**
* Returns the number of failures recorded in the current state when the state is CLOSED or HALF_OPEN. When the state
* is OPEN, returns the failures recorded during the previous CLOSED state.
*
* For count based thresholds, the max number of failures is based on the {@link
* CircuitBreakerConfig#getFailureThreshold() failure threshold}. For time based thresholds, the number of failures
* may vary within the {@link CircuitBreakerConfig#getFailureThresholdingPeriod() failure thresholding period}.
*
*/
long getFailureCount();
/**
* The percentage rate of failed executions, from 0 to 100, in the current state when the state is CLOSED or
* HALF_OPEN. When the state is OPEN, returns the rate recorded during the previous CLOSED state.
*
* The rate is based on the configured {@link CircuitBreakerConfig#getFailureThresholdingCapacity() failure
* thresholding capacity}.
*
*/
int getFailureRate();
/**
* Returns the number of successes recorded in the current state when the state is CLOSED or HALF_OPEN. When the state
* is OPEN, returns the successes recorded during the previous CLOSED state.
*
* The max number of successes is based on the {@link CircuitBreakerConfig#getSuccessThreshold() success threshold}.
*
*/
int getSuccessCount();
/**
* The percentage rate of successful executions, from 0 to 100, in the current state when the state is CLOSED or
* HALF_OPEN. When the state is OPEN, returns the rate recorded during the previous CLOSED state.
*
* The rate is based on the configured {@link CircuitBreakerConfig#getSuccessThresholdingCapacity() success
* thresholding capacity}.
*
*/
int getSuccessRate();
/**
* Returns whether the circuit is closed.
*/
boolean isClosed();
/**
* Returns whether the circuit is half open.
*/
boolean isHalfOpen();
/**
* Returns whether the circuit is open.
*/
boolean isOpen();
/**
* Records an execution failure.
*/
void recordFailure();
/**
* Records an execution {@code failure} as a success or failure based on the failure configuration.
*/
void recordFailure(Throwable failure);
/**
* Records an execution {@code result} as a success or failure based on the failure configuration.
*/
void recordResult(R result);
/**
* Records an execution success.
*/
void recordSuccess();
}