A Minimalistic Circuit Breaker for Java EE applications
Switch branches/tags
Clone or download
Permalink
Failed to load latest commit information.
breakr-st Switched to v0.0.2 Nov 26, 2015
breakr [maven-release-plugin] prepare for next development iteration Apr 5, 2016
.gitignore Gitignore fixed Nov 26, 2015
LICENSE Initial commit Oct 24, 2015
README.md Tests refactored Jan 27, 2016

README.md

breakr

A Minimalistic Circuit Breaker for Java EE applications

breakr comes as a single, 6 kB jar without any further configuration. Just add the dependency below to your pom.xml and put the annotation @Interceptors(Breakr.class) on a brittle class.

Checkout porcupine for monitorable threadpools (bulkheads and handshaking) implementation.

#Installation

        <dependency>
            <groupId>com.airhacks</groupId>
            <artifactId>breakr</artifactId>
            <version>[CURRENT_VERSION]</version>
        </dependency>

#Usage

Ignoring exception throwers

import com.airhacks.breakr.Breakr;
import com.airhacks.breakr.CloseCircuit;
import com.airhacks.breakr.IgnoreCallsWhen;
import javax.ejb.ConcurrencyManagement;
import javax.ejb.ConcurrencyManagementType;
import javax.ejb.Singleton;
import javax.interceptor.Interceptors;

/**
 * Breakr is implemented as an Java EE interceptor. Annotate a
 * <code>@Singleton</code> CDI or EJB to activate the call supervision.
 */
@Singleton
@Interceptors(Breakr.class)
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class Brittle {

    /**
     * With the optional <code>@IgnoreCallsWhen</code> you can override the
     * (timeout = 1s, maxFailures = 5).
     */
    @IgnoreCallsWhen(failures = 2)
    public String test(boolean exception) throws Exception {
        if (exception) {
            throw new Exception("For test purposes only");
        }
        return "works " + System.currentTimeMillis();
    }

    /**
     * Calling a method annotated with <code>@CloseCircuit</code> resets all
     * counters and closes the circuit.
     */
    @CloseCircuit
    public void reset() {
    }
}

Ignoring slow methods

@Singleton
@Interceptors(Breakr.class)
public class Slow {

    @IgnoreCallsWhen(slowerThanMillis = 10)
    public String tooSlow() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException ex) {}
        return "Slow: " + System.currentTimeMillis();
    }

}

Implementing custom behavior

The decision when the circuit is opened or closed are made by the class com.airhacks.breakr.Circuit

public class Circuit {

    protected AtomicLong failureCounter;

    @PostConstruct
    public void init() {
        this.failureCounter = new AtomicLong(0);
    }

    public void newException(Exception ex) {
        this.failureCounter.incrementAndGet();
    }

    public void newTimeout(long duration) {
        this.failureCounter.incrementAndGet();
    }

    public boolean isOpen(long maxFailures) {
        return (this.failureCounter.get() >= maxFailures);
    }

    public void reset() {
        failureCounter.set(0);
    }

}

To override the default behavior, simply specialize the class and inject your own behavior:

@ApplicationScoped
@Specializes
public class CustomCircuit extends Circuit {

    private boolean open;

    @Override
    public boolean isOpen(long maxFailures) {
        return open;
    }

    public long getFailureCount() {
        return failureCounter.get();
    }

    public void setOpen(boolean open) {
        this.open = open;
    }

}