2012-06-01 08:24:47 -04:00
|
|
|
/**
|
2017-01-04 17:37:10 +01:00
|
|
|
* Copyright (C) 2009-2017 Lightbend Inc. <http://www.lightbend.com>
|
2012-06-01 08:24:47 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
package docs.circuitbreaker
|
|
|
|
|
|
|
|
|
|
//#imports1
|
2012-09-21 14:50:06 +02:00
|
|
|
import scala.concurrent.duration._
|
2012-06-01 08:24:47 -04:00
|
|
|
import akka.pattern.CircuitBreaker
|
2012-10-03 13:30:00 +02:00
|
|
|
import akka.pattern.pipe
|
2016-09-02 19:28:49 +08:00
|
|
|
import akka.actor.{ Actor, ActorLogging, ActorRef }
|
2016-08-30 18:09:19 +09:00
|
|
|
|
2012-07-04 15:25:30 +02:00
|
|
|
import scala.concurrent.Future
|
2017-03-30 15:51:51 +01:00
|
|
|
import scala.util.{ Failure, Success, Try }
|
2012-06-01 08:24:47 -04:00
|
|
|
|
|
|
|
|
//#imports1
|
|
|
|
|
|
2012-06-01 21:29:47 +02:00
|
|
|
class CircuitBreakerDocSpec {}
|
2012-06-01 08:24:47 -04:00
|
|
|
|
|
|
|
|
//#circuit-breaker-initialization
|
2012-10-03 13:30:00 +02:00
|
|
|
class DangerousActor extends Actor with ActorLogging {
|
|
|
|
|
import context.dispatcher
|
2012-06-01 08:24:47 -04:00
|
|
|
|
|
|
|
|
val breaker =
|
2016-06-02 14:06:57 +02:00
|
|
|
new CircuitBreaker(
|
|
|
|
|
context.system.scheduler,
|
2012-10-03 13:30:00 +02:00
|
|
|
maxFailures = 5,
|
|
|
|
|
callTimeout = 10.seconds,
|
2013-03-28 23:45:48 +01:00
|
|
|
resetTimeout = 1.minute).onOpen(notifyMeOnOpen())
|
2012-06-01 08:24:47 -04:00
|
|
|
|
2013-03-28 23:45:48 +01:00
|
|
|
def notifyMeOnOpen(): Unit =
|
2012-06-01 08:24:47 -04:00
|
|
|
log.warning("My CircuitBreaker is now open, and will not close for one minute")
|
2012-06-01 21:29:47 +02:00
|
|
|
//#circuit-breaker-initialization
|
2012-06-01 08:24:47 -04:00
|
|
|
|
2012-06-01 21:29:47 +02:00
|
|
|
//#circuit-breaker-usage
|
2012-06-01 08:24:47 -04:00
|
|
|
def dangerousCall: String = "This really isn't that dangerous of a call after all"
|
|
|
|
|
|
|
|
|
|
def receive = {
|
2013-12-03 16:34:26 +01:00
|
|
|
case "is my middle name" =>
|
2014-01-16 15:16:35 +01:00
|
|
|
breaker.withCircuitBreaker(Future(dangerousCall)) pipeTo sender()
|
2013-12-03 16:34:26 +01:00
|
|
|
case "block for me" =>
|
2014-01-16 15:16:35 +01:00
|
|
|
sender() ! breaker.withSyncCircuitBreaker(dangerousCall)
|
2012-06-01 08:24:47 -04:00
|
|
|
}
|
2012-06-01 21:29:47 +02:00
|
|
|
//#circuit-breaker-usage
|
2012-06-01 08:24:47 -04:00
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2016-09-02 19:28:49 +08:00
|
|
|
class TellPatternActor(recipient: ActorRef) extends Actor with ActorLogging {
|
2016-08-30 18:09:19 +09:00
|
|
|
import context.dispatcher
|
|
|
|
|
|
|
|
|
|
val breaker =
|
|
|
|
|
new CircuitBreaker(
|
|
|
|
|
context.system.scheduler,
|
|
|
|
|
maxFailures = 5,
|
|
|
|
|
callTimeout = 10.seconds,
|
|
|
|
|
resetTimeout = 1.minute).onOpen(notifyMeOnOpen())
|
|
|
|
|
|
|
|
|
|
def notifyMeOnOpen(): Unit =
|
|
|
|
|
log.warning("My CircuitBreaker is now open, and will not close for one minute")
|
|
|
|
|
|
|
|
|
|
//#circuit-breaker-tell-pattern
|
|
|
|
|
import akka.actor.ReceiveTimeout
|
|
|
|
|
|
|
|
|
|
def receive = {
|
|
|
|
|
case "call" if breaker.isClosed => {
|
|
|
|
|
recipient ! "message"
|
|
|
|
|
}
|
|
|
|
|
case "response" => {
|
|
|
|
|
breaker.succeed()
|
|
|
|
|
}
|
|
|
|
|
case err: Throwable => {
|
|
|
|
|
breaker.fail()
|
|
|
|
|
}
|
|
|
|
|
case ReceiveTimeout => {
|
|
|
|
|
breaker.fail()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#circuit-breaker-tell-pattern
|
2017-01-04 17:37:10 +01:00
|
|
|
}
|
2017-03-30 15:51:51 +01:00
|
|
|
|
|
|
|
|
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 =>
|
|
|
|
|
}
|
|
|
|
|
}
|