--- CircuitBreaker/src/dk/thoerup/curcuitbreaker/CircuitBreaker.java 2009/10/09 06:45:40 426 +++ miscJava/CircuitBreaker/src/dk/thoerup/circuitbreaker/CircuitBreaker.java 2015/03/20 08:52:49 2448 @@ -1,9 +1,14 @@ -package dk.thoerup.curcuitbreaker; +package dk.thoerup.circuitbreaker; -import java.util.logging.Logger; -import dk.thoerup.curcuitbreaker.notification.Notifier; -import dk.thoerup.curcuitbreaker.notification.NullNotifier; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import dk.thoerup.circuitbreaker.config.BreakerConfig; +import dk.thoerup.circuitbreaker.config.StaticConfig; +import dk.thoerup.circuitbreaker.notification.NotiferHelper; +import dk.thoerup.circuitbreaker.notification.Notifier; +import dk.thoerup.circuitbreaker.notification.NullNotifier; /* Simple CircuitBreaker implementation - snipped from http://www.jroller.com/kenwdelong/entry/circuit_breaker_in_java * @@ -32,7 +37,7 @@ try { String s = (String) cb.invoke(new TestInvocation("http://rafiki/test")); response.getWriter().print(s); - } catch (Throwable e) { + } catch (Exception e) { logger.warning( e.getMessage() ); response.sendError(500); return; @@ -43,10 +48,8 @@ public class CircuitBreaker{ - Logger logger = Logger.getLogger(CircuitBreaker.class.getName()); - - private CircuitBreakerState currentState; + private volatile CircuitBreakerState currentState; private final OpenState open = new OpenState(); private final HalfOpenState halfOpen = new HalfOpenState(); @@ -54,19 +57,32 @@ private String name; + private ExecutorService executor = null; private Notifier notifier = new NullNotifier(); - public CircuitBreaker(String name, int threshold, long timeoutMS) { - closed.setThreshold(threshold); - open.setTimeout(timeoutMS); + @Deprecated + public CircuitBreaker(String name, int threshold, int timeoutMS) { + this(name, new StaticConfig(threshold, timeoutMS) ); + } + + public CircuitBreaker(String name, BreakerConfig config) { + closed.setThreshold(config); + open.setTimeout(config); this.name = name; - - reset(); + + //set correct intial state + internalReset(); + } + + public synchronized void shutdown() { + if (executor != null) { + executor.shutdown(); + } } - public Object invoke(CircuitInvocation invocation) throws Throwable + public Object invoke(CircuitInvocation invocation) throws Exception { Object result = null; try @@ -75,30 +91,39 @@ result = invocation.proceed(); getState().postInvoke(this); } - catch(Throwable t) + catch(Exception e) { - getState().onError(this, t); - throw t; + getState().onError(this, e); + throw e; } return result; } public void tripBreaker() { - synchronized(this) { + commonTripBreaker(Notifier.Event.BreakerTripped); + } + + //a re-trip should basically do the same as a normal trip, but it is here just to differentiate the two different events + public void retripBreaker() { + commonTripBreaker(Notifier.Event.BreakerRetripped); + } + + private void commonTripBreaker(Notifier.Event event) { + synchronized(this) { if (currentState != open) { // TODO:Is this conditional necessary ?? open.trip(); currentState = open; - notifier.sendNotification(name, Notifier.Event.BreakerTripped); + notifier.sendNotification(this, event); } - } + } } - + public void attemptReset() { synchronized(this) { if (currentState != halfOpen) { // TODO:Is this conditional necessary ?? currentState = halfOpen; - notifier.sendNotification(name, Notifier.Event.BreakerAttemptReset); + notifier.sendNotification(this, Notifier.Event.BreakerAttemptReset); } } @@ -107,12 +132,18 @@ public void reset() { synchronized(this) { if (currentState != closed) { // TODO: Is this conditional necessary ?? - currentState = closed; - notifier.sendNotification(name, Notifier.Event.BreakerReset); + internalReset(); + notifier.sendNotification(this, Notifier.Event.BreakerReset); } } } + //This one actually sets the correct closed/reset state + private void internalReset() { + closed.resetFailureCount(); + currentState = closed; + } + private CircuitBreakerState getState() { synchronized(this) { @@ -120,6 +151,14 @@ } } + public boolean isClosed() { + return (getState() == closed); + } + + public boolean isOpen() { + return (getState() == open); + } + public String getName() { return name; } @@ -156,8 +195,18 @@ this.notifier = notifier; } - public String getNotifierName() { - return notifier.getClass().getName(); + public String getNotifierName() { + return NotiferHelper.getName(notifier); + } + + public synchronized ExecutorService getExecutor() { + + if (executor == null) { + executor = Executors.newFixedThreadPool(1); + } + + return executor; + } }