Add docs for circuit breaker new feature #22596
This commit is contained in:
parent
626d07edca
commit
d3de9d40cd
3 changed files with 106 additions and 4 deletions
|
|
@ -32,9 +32,9 @@ appropriate while the breaker is open.
|
|||
The Akka library provides an implementation of a circuit breaker called
|
||||
:class:`akka.pattern.CircuitBreaker` which has the behavior described below.
|
||||
|
||||
=================
|
||||
================
|
||||
What do they do?
|
||||
=================
|
||||
================
|
||||
* During normal operation, a circuit breaker is in the `Closed` state:
|
||||
* Exceptions or calls exceeding the configured `callTimeout` increment a failure counter
|
||||
* Successes reset the failure count to zero
|
||||
|
|
@ -119,6 +119,48 @@ Java
|
|||
There is also a :class:`CircuitBreakerProxy` actor that you can use, which is an alternative implementation of the pattern.
|
||||
The main difference is that it is intended to be used only for request-reply interactions with another actor. See :ref:`Circuit Breaker Actor <circuit-breaker-proxy>`
|
||||
|
||||
--------------------------------
|
||||
Control failure count explicitly
|
||||
--------------------------------
|
||||
|
||||
By default, the circuit breaker treat :class:`Exception` as failure in synchronized API, or failed :class:`Future` as failure in future based API.
|
||||
Failure will increment failure count, when failure count reach the `maxFailures`, circuit breaker will be opened.
|
||||
However, some applications might requires certain exception to not increase failure count, or vice versa,
|
||||
sometime we want to increase the failure count even if the call succeeded.
|
||||
Akka circuit breaker provides a way to achieve such use case:
|
||||
|
||||
* `withCircuitBreaker`
|
||||
* `withSyncCircuitBreaker`
|
||||
|
||||
* `callWithCircuitBreaker`
|
||||
* `callWithCircuitBreakerCS`
|
||||
* `callWithSyncCircuitBreaker`
|
||||
|
||||
All methods above accepts an argument ``defineFailureFn``
|
||||
|
||||
~~~~~
|
||||
Scala
|
||||
~~~~~
|
||||
|
||||
Type of ``defineFailureFn``: ``Try[T] ⇒ Boolean``
|
||||
|
||||
This is a function which takes in a :class:`Try[T]` and return a :class:`Boolean`. The :class:`Try[T]` correspond to the :class:`Future[T]` of the protected call. This function should return ``true`` if the call should increase failure count, else false.
|
||||
|
||||
.. includecode:: code/docs/circuitbreaker/CircuitBreakerDocSpec.scala
|
||||
:include: even-no-as-failure
|
||||
|
||||
~~~~
|
||||
Java
|
||||
~~~~
|
||||
|
||||
Type of ``defineFailureFn``: :class:`BiFunction[Optional[T], Optional[Throwable], java.lang.Boolean]`
|
||||
|
||||
For Java Api, the signature is a bit different as there's no :class:`Try` in Java, so the response of protected call is modelled using :class:`Optional[T]` for succeeded return value and :class:`Optional[Throwable]` for exception, and the rules of return type is the same.
|
||||
Ie. this function should return ``true`` if the call should increase failure count, else false.
|
||||
|
||||
.. includecode:: code/docs/circuitbreaker/EvenNoFailureJavaExample.java
|
||||
:include: even-no-as-failure
|
||||
|
||||
-------------
|
||||
Low level API
|
||||
-------------
|
||||
|
|
@ -140,9 +182,9 @@ Scala
|
|||
:include: circuit-breaker-tell-pattern
|
||||
|
||||
|
||||
~~~~~
|
||||
~~~~
|
||||
Java
|
||||
~~~~~
|
||||
~~~~
|
||||
|
||||
.. includecode:: code/docs/circuitbreaker/TellPatternJavaActor.java
|
||||
:include: circuit-breaker-tell-pattern
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import akka.pattern.pipe
|
|||
import akka.actor.{ Actor, ActorLogging, ActorRef }
|
||||
|
||||
import scala.concurrent.Future
|
||||
import scala.util.{ Failure, Success, Try }
|
||||
|
||||
//#imports1
|
||||
|
||||
|
|
@ -76,3 +77,29 @@ class TellPatternActor(recipient: ActorRef) extends Actor with ActorLogging {
|
|||
}
|
||||
//#circuit-breaker-tell-pattern
|
||||
}
|
||||
|
||||
class EvenNoFailureActor extends Actor {
|
||||
import context.dispatcher
|
||||
//#even-no-as-failure
|
||||
def luckyNumber(): Future[Int] = {
|
||||
val evenNumberAsFailure: Try[Int] => Boolean = {
|
||||
case Success(n) => n % 2 == 0
|
||||
case Failure(_) => true
|
||||
}
|
||||
|
||||
val breaker =
|
||||
new CircuitBreaker(
|
||||
context.system.scheduler,
|
||||
maxFailures = 5,
|
||||
callTimeout = 10.seconds,
|
||||
resetTimeout = 1.minute)
|
||||
|
||||
// this call will return 8888 and increase failure count at the same time
|
||||
breaker.withCircuitBreaker(Future(8888), evenNumberAsFailure)
|
||||
}
|
||||
//#even-no-as-failure
|
||||
|
||||
override def receive = {
|
||||
case x: Int =>
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
package docs.circuitbreaker;
|
||||
|
||||
import akka.actor.AbstractActor;
|
||||
import akka.pattern.CircuitBreaker;
|
||||
import scala.concurrent.duration.Duration;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class EvenNoFailureJavaExample extends AbstractActor {
|
||||
//#even-no-as-failure
|
||||
private final CircuitBreaker breaker;
|
||||
|
||||
public EvenNoFailureJavaExample() {
|
||||
this.breaker = new CircuitBreaker(
|
||||
getContext().dispatcher(), getContext().system().scheduler(),
|
||||
5, Duration.create(10, "s"), Duration.create(1, "m"));
|
||||
}
|
||||
|
||||
public int luckyNumber() {
|
||||
BiFunction<Optional<Integer>, Optional<Throwable>, Boolean> evenNoAsFailure =
|
||||
(result, err) -> (result.isPresent() && result.get() % 2 == 0);
|
||||
|
||||
// this will return 8888 and increase failure count at the same time
|
||||
return this.breaker.callWithSyncCircuitBreaker(() -> 8888, evenNoAsFailure);
|
||||
}
|
||||
|
||||
//#even-no-as-failure
|
||||
@Override
|
||||
public Receive createReceive() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue