Higher Order Blog

home

Clojure circuit breaker

23 Nov 2009

[Update Jan 1., 2010: A couple of people have been linking and twitting this, so I've made the blog entry match the current Clojure version at github. Code works in the 'new' branch of Clojure: tested with commit 3ae9e8874d43f9fd37e59bb7ea8cce0f85bac101. There is support for creating several circuit breakers wrapping given functions]. As an exercise in Clojure, I've implemented a mostly functional version of Michael Nygaard's stability pattern "Circuit breaker" (http://www.pragprog.com/titles/mnee/release-it). The implementation uses the new constructs deftype and defprotocol (which are looking really interesting to me!). The implementation maintains a single identity named "state" which is an atom holding the current state (open, closed, initial-half-open or pending-half-open). More on deftype and defprotocol can be found here. Here is the code that defines the states and the state transitions (requires JavaScript; otherwise use this link). Notice how the events 'on-before-call', 'on-success' and 'on-error' are implemented as a protocol defining state-transition functions. I really like the features Rich is adding to Clojure - to me it makes modeling so much more natural (with an OO-background), while retaining the benefits of functional programming. Notice how this snipplet defines the transition functions, the four states as well as an "abstract" implementation of the state transitions. The abs-transitions can be used as default implementations when extending the protocol to the state-types. In Java, this would correspond to an interface (CircuitBreakerTransitions), an abstract super-class implementing the interface, and four immutable classes (the states). However, Clojures deftype and defprotocol does not create a type-hierarchy, and is much more dynamic (you can always define how a given type extends to a protocol - it is not fixed at type definition time). Here is how I extended my types to the protocol: (http://gist.github.com/267169) This defines a completely functional transition-system between the four states. I think this reads really well, for example consider the on-error event in the closed state: this checks to see if the states fail-count is equal to the threshold defined in the policy, if so it transitions to the open state, recording the current time (OpenState p (System/currentTimeMillis)) (preserving the policy); otherwise it transitions to a closed state with a higher fail-count. The actual circuit breaker uses these transition functions: (http://gist.github.com/267172) The state of a circuit breaker is an atom (the only mutable construct in this example). The function wrap takes a function f and returns a "wrapped" version of f, which implements the circuit breaker functionality around f. Notice how dead-simple this is to test: (http://gist.github.com/267173) Full Source: http://github.com/krukow/clojure-circuit-breaker