* Add Circuit Breaker to akka.pattern for general use. Circuit breaker implementation as described by Michael T. Nygard in Release It!. Fixes #1734
* Uses finite state machine for three states: Closed, Open, Half-Open
* Closed state allows calls through, and on sequential failures exceeding the max# set - transitions to Open state. Intervening successes cause the failure count to reset to 0
* Open state throws a CircuitOpenException on every call until the reset timeout is reached which causes a transition to Half-Open state
* Half-Open state will allow the next single call through, if it succeeds - transition to Closed state, if it fails - transition back to Open state, starting the reset timer again
* Allow configuration for the call and reset timeouts, as well as the maximum number of sequential failures before opening
* Supports async or synchronous call protection
* Callbacks are supported for state entry into Closed, Open, Half-Open. These are run in the supplied execution context
* Both thrown exceptions and calls exceeding max call time are considered failures
* Uses akka scheduler for timer events
* Integrated into File-Based durable mailbox
* Sample documented for other durable mailboxes
This commit is contained in:
parent
85c263e077
commit
6a415f0e9b
15 changed files with 1266 additions and 25 deletions
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package docs.circuitbreaker
|
||||
|
||||
//#imports1
|
||||
import akka.util.duration._ // small d is important here
|
||||
import akka.pattern.CircuitBreaker
|
||||
import akka.actor.Actor
|
||||
import akka.dispatch.Future
|
||||
import akka.event.Logging
|
||||
|
||||
//#imports1
|
||||
|
||||
class CircuitBreakerDocSpec { }
|
||||
|
||||
//#circuit-breaker-initialization
|
||||
class DangerousActor extends Actor {
|
||||
|
||||
val log = Logging(context.system, this)
|
||||
implicit val executionContext = context.dispatcher
|
||||
val breaker =
|
||||
new CircuitBreaker(context.system.scheduler, 5, 10.seconds, 1.minute)
|
||||
.onOpen(notifyMeOnOpen)
|
||||
|
||||
def notifyMeOnOpen =
|
||||
log.warning("My CircuitBreaker is now open, and will not close for one minute")
|
||||
//#circuit-breaker-initialization
|
||||
|
||||
//#circuit-breaker-usage
|
||||
def dangerousCall: String = "This really isn't that dangerous of a call after all"
|
||||
|
||||
def receive = {
|
||||
case "is my middle name" =>
|
||||
sender ! breaker.withCircuitBreaker(Future(dangerousCall))
|
||||
case "block for me" =>
|
||||
sender ! breaker.withSyncCircuitBreaker(dangerousCall)
|
||||
}
|
||||
//#circuit-breaker-usage
|
||||
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue