package com.kendelong.util.circuitbreaker; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; /** * This is the state that we go to when we are detecting serious errors from the * remote service. In this state, the breaker is tripped and we don't send any calls * to the remote service, thus giving it time to catch its breath and perhaps come * online. After "timeout" milliseconds, we go "half-open" and make another * connection attempt. * * @author kdelong */ public class OpenState implements ICircuitBreakerState { private final AtomicInteger timeout = new AtomicInteger(); private final AtomicLong tripTime = new AtomicLong(); private final int DEFAULT_TIMEOUT = 60000; public OpenState() { timeout.set(DEFAULT_TIMEOUT); } public void preInvoke(CircuitBreakerAspect circuitBreakerAspect) throws Throwable { long now = System.currentTimeMillis(); long elapsed = now - tripTime.get(); if(elapsed > timeout.get()) { circuitBreakerAspect.attemptReset(); } else { throw new CircuitBreakerException("Circuit Breaker is open; calls are failing fast"); } } public void postInvoke(CircuitBreakerAspect circuitBreakerAspect) throws Throwable { // NO OP } public void onError(CircuitBreakerAspect circuitBreakerAspect, Throwable t) throws Throwable { // NO OP } void trip() { long now = System.currentTimeMillis(); tripTime.set(now); } void setRecoveryTimeout(int timeoutVal) { timeout.set(timeoutVal); } public int getRecoveryTimeout() { return timeout.get(); } public long getTimeToNextRetry() { long now = System.currentTimeMillis(); long trip = tripTime.get(); long timeOut = timeout.get(); return timeOut - (now - trip); } }