Circuit breaker pattern in Deja vu

This post is part of a series about the framework Deja vu.

The circuit breaker pattern provides a way of ensuring your application will not wait unnecessary on calls to integration points known to be slow or down (a good description can be found here).

Since Deja vu uses the term integration points, it seems obvious to add support for this pattern directly in the framework.

The annotation Impure can actually take an argument, integrationPoint. This argument will tell the framework the name of the circuit breaker to use for this integration point.

Example

An example of an impure method guarded by integration point called ‘cb1’:

public class WithCircuitBreaker {

    @Traced
    public void run(Integer input) {
        poke(input);
    }

    @Impure( integrationPoint = "cb1")
    private void poke(int input) {
        if ( input == 1 ) {
            throw new MyOwnException();
        }
    }
}

A circuit breaker instance manages the state of a circuit breaker and is instantiated with parameters name, timeout milliseconds, and exception threshold. Such an instance must be passed to the framework which will use it on @Impure methods with integration points of this name.

    @Test
    public void exceed_threshold() {
        // name is cb1, timeout is 500 milliseconds, and 2 exceptions in a row
        // will cause it to open
        CircuitBreaker breaker = new CircuitBreaker("cb1", 500, 2);
        DejaVuAspect.addCircuitBreaker( breaker );
        WithCircuitBreaker example = new WithCircuitBreaker();
        try {
            Assert.assertEquals("Closed", breaker.getState());
            example.run(1);
            Assert.fail("first crash");
        } catch (MyOwnException e ) {
            Assert.assertEquals("Closed", breaker.getState());
            try {
                example.run(1);
                Assert.fail("second crash");
            } catch (MyOwnException ee ) {
                Assert.assertEquals("Open", breaker.getState());
                try {
                    example.run(1);
                    Assert.fail("third must be of type CircuitOpenException");
                } catch (CircuitOpenException eee ) {
                    Assert.assertEquals("Open", breaker.getState());
                    try {
                        Thread.sleep( 600 );
                        // should now be set to half open
                        Assert.assertEquals("Half_open", breaker.getState());
                        // should succeed
                        example.run(0);
                        Assert.assertEquals("Closed", breaker.getState());
                    } catch (InterruptedException e1) {
                        Assert.fail();
                    }
                }
            }
        }
    }

Calling it twice with argument ‘1’ will change the state from ‘Closed’ to ‘Open’. As the state is ‘Open’ all calls to it will result in CircuitOpenException which is thrown without the method being invoked. But if we wait for 600 milliseconds the state will have changed to Half_open. Such a state means the result of the next invocation change the state to either ‘Open’ or ‘Closed’. We run it with input ‘0’ meaning is succeeds so we go to state ‘Closed’.

This post is part of a series about the framework Deja vu. Next: Multi-threading

This Post Has One Comment

Leave a Reply