/*
* Copyright 2016 LINE Corporation
*
* LINE Corporation licenses this file to you 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.
*/
/**
* Failure detection and fallback mechanism based on
* <a href="http://martinfowler.com/bliki/CircuitBreaker.html">circuit breaker pattern</a>.
*
* <h1>Setup Client with Circuit Breaker</h1>
* <h2>Example</h2>
* <pre>{@code
* Iface helloClient = new ClientBuilder("tbinary+http://127.0.0.1:8080/hello")
* .decorator(
* CircuitBreakerClient.newDecorator(
* new CircuitBreakerBuilder("hello").build()
* )
* )
* .build(Iface.class);
* }</pre>
*
* <h1>A Unit of Failure Detection</h1>
* You can specify a unit of failure detection from the following:
* <ul>
* <li>per remote service (as shown in the example above)</li>
* <li>per method</li>
* <li>per remote host</li>
* <li>per remote host and method</li>
* </ul>
* <h2>Example</h2>
* <pre>{@code
* // Setup with per-method failure detection
* AsyncIface helloClient = new ClientBuilder("tbinary+http://127.0.0.1:8080/hello")
* .decorator(
* CircuitBreakerClient.newPerMethodDecorator(
* method -> new CircuitBreakerBuilder(method).build()
* )
* )
* .build(AsyncIface.class);
* }</pre>
*
* <h1>Fallback</h1>
* Once a failure is detected, A {@link com.linecorp.armeria.client.circuitbreaker.FailFastException} is thrown
* from the client. You can write a fallback code by catching the exception.
* <h2>Example</h2>
* <pre>{@code
* try {
* helloClient.hello("line");
* } catch (TException e) {
* // error handling
* } catch (FailFastException e) {
* // fallback code
* }
* }</pre>
*
* <h2>Example in Async Client</h2>
* <pre>{@code
* helloClient.hello("line", new AsyncMethodCallback() {
* public void onComplete(Object response) {
* // response handling
* }
* public void onError(Exception e) {
* if (e instanceof TException) {
* // error handling
* } else if (e instanceof FailFastException) {
* // fallback code
* }
* }
* });
* }</pre>
*
* <h1>Circuit States and Transitions</h1>
* The circuit breaker provided by this package is implemented as a finite state machine consisting of the
* following states and transitions.
*
* <h2>{@code CLOSED}</h2>
* The initial state. All requests are sent to the remote service. If the failure rate exceeds
* the specified threshold, the state turns into {@code OPEN}.
*
* <h2>{@code OPEN}</h2>
* All requests fail immediately without calling the remote service. After the specified time,
* the state turns into {@code HALF_OPEN}.
*
* <h2>{@code HALF_OPEN}</h2>
* Only one trial request is sent at a time.
* <ul>
* <li>If it succeeds, the state turns into {@code CLOSED}.</li>
* <li>If it fails, the state returns to {@code OPEN}.</li>
* <li>If it doesn't complete within a certain time,
* another trial request will be sent again.</li>
* </ul>
*
* <h1>Circuit Breaker Configurations</h1>
* The behavior of a circuit breaker can be modified via
* {@link com.linecorp.armeria.client.circuitbreaker.CircuitBreakerBuilder}.
*
* <h2>{@code failureRateThreshold}</h2>
* The threshold of failure rate(= failure/total) to detect a remote service fault.
*
* <h2>{@code minimumRequestThreshold}</h2>
* The minimum number of requests within the time window necessary to detect a remote service
* fault.
* <h2>{@code circuitOpenWindow}</h2>
* The duration of {@code OPEN} state.
*
* <h2>{@code trialRequestInterval}</h2>
* The interval of trial request in {@code HALF_OPEN} state.
*
* <h2>{@code counterSlidingWindow}</h2>
* The time length of sliding window to accumulate the count of events.
*
* <h2>{@code counterUpdateInterval}</h2>
* The interval that a circuit breaker can see the latest count of events.
*
* <h2>{@code exceptionFilter}</h2>
* A filter that decides whether a circuit breaker should deal with a given error.
*/
package com.linecorp.armeria.client.circuitbreaker;