Created
June 23, 2015 00:45
-
-
Save rubanm/90597f4d098cd0cb002d to your computer and use it in GitHub Desktop.
Circuit breaker sketch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import scala.util.{ Failure, Success, Try } | |
// based on http://martinfowler.com/bliki/CircuitBreaker.html | |
object CircuitBreaker { | |
def apply[T](_timeout: Long, _threshold: Int)(work: () => T): CircuitBreaker[T] = | |
new FailureThresholdCircuitBreaker[T](work) { | |
override protected def timeout = _timeout | |
override protected def threshold = _threshold | |
} | |
} | |
trait CircuitBreaker[T] { | |
def call: T | |
} | |
abstract class FailureThresholdCircuitBreaker[T](work: () => T) extends CircuitBreaker[T] { | |
private[this] var state: State = Closed | |
private[this] var numFailures: Int = 0 | |
private[this] var failurePoint: Long = 0 | |
protected def threshold: Int | |
protected def timeout: Long | |
override def call: T = | |
state match { | |
case Closed => | |
Try(work()) match { | |
case Success(t) => t | |
case Failure(e) => | |
numFailures = numFailures + 1 | |
if (numFailures > threshold) { | |
failurePoint = System.currentTimeMillis | |
state = Open | |
} | |
throw e | |
} | |
case HalfOpen => | |
Try(work()) match { | |
case Success(t) => | |
numFailures = 0 | |
state = Closed | |
t | |
case Failure(e) => | |
failurePoint = System.currentTimeMillis | |
state = Open | |
throw e | |
} | |
case Open => | |
if (System.currentTimeMillis - failurePoint >= timeout) { | |
state = HalfOpen | |
call | |
} else | |
throw new CircuitBreakerOpenException | |
} | |
} | |
sealed trait State | |
case object Open extends State | |
case object Closed extends State | |
case object HalfOpen extends State | |
case class CircuitBreakerOpenException extends RuntimeException |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment