Skip to content

Instantly share code, notes, and snippets.

@rubanm
Created June 23, 2015 00:45
Show Gist options
  • Save rubanm/90597f4d098cd0cb002d to your computer and use it in GitHub Desktop.
Save rubanm/90597f4d098cd0cb002d to your computer and use it in GitHub Desktop.
Circuit breaker sketch
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