/[projects]/miscJava/CircuitBreaker/src/main/java/dk/thoerup/circuitbreaker/CircuitBreaker.java
ViewVC logotype

Diff of /miscJava/CircuitBreaker/src/main/java/dk/thoerup/circuitbreaker/CircuitBreaker.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

CircuitBreaker/src/dk/thoerup/curcuitbreaker/CircuitBreaker.java revision 394 by torben, Mon Oct 5 19:46:15 2009 UTC CircuitBreaker/src/dk/thoerup/circuitbreaker/CircuitBreaker.java revision 1306 by torben, Tue Apr 19 15:22:09 2011 UTC
# Line 1  Line 1 
1  package dk.thoerup.curcuitbreaker;  package dk.thoerup.circuitbreaker;
2    
3  import java.util.logging.Logger;  
4    import java.util.concurrent.ExecutorService;
5    import java.util.concurrent.Executors;
6    
7    import dk.thoerup.circuitbreaker.config.BreakerConfig;
8    import dk.thoerup.circuitbreaker.config.StaticConfig;
9    import dk.thoerup.circuitbreaker.notification.NotiferHelper;
10    import dk.thoerup.circuitbreaker.notification.Notifier;
11    import dk.thoerup.circuitbreaker.notification.NullNotifier;
12    
13  /* Simple CircuitBreaker implementation - snipped from http://www.jroller.com/kenwdelong/entry/circuit_breaker_in_java  /* Simple CircuitBreaker implementation - snipped from http://www.jroller.com/kenwdelong/entry/circuit_breaker_in_java
14   *   *
15   *  example of how it can be used   *  example of how it can be used
16  protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
17     private CircuitBreaker cb = new CircuitBreaker("test", 5, 10000);
18     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
19                  class TestInvocation implements CircuitInvocation {                  class TestInvocation implements CircuitInvocation {
20                          String url;                          String url;
21                          public TestInvocation(String url) {                          public TestInvocation(String url) {
# Line 27  protected void doGet(HttpServletRequest Line 37  protected void doGet(HttpServletRequest
37                  try {                  try {
38                          String s = (String) cb.invoke(new TestInvocation("http://rafiki/test"));                          String s = (String) cb.invoke(new TestInvocation("http://rafiki/test"));
39                          response.getWriter().print(s);                          response.getWriter().print(s);
40                  } catch (Throwable e) {                  } catch (Exception e) {
41                          logger.warning( e.getMessage() );                          logger.warning( e.getMessage() );
42                          response.sendError(500);                          response.sendError(500);
43                          return;                          return;
# Line 38  protected void doGet(HttpServletRequest Line 48  protected void doGet(HttpServletRequest
48    
49    
50  public class CircuitBreaker{  public class CircuitBreaker{
         Logger logger = Logger.getLogger(CircuitBreaker.class.getName());  
   
51                    
52          private CircuitBreakerState currentState;          private volatile CircuitBreakerState currentState;
53                    
54          private OpenState open = new OpenState();          private final OpenState open = new OpenState();
55          private HalfOpenState halfOpen = new HalfOpenState();          private final HalfOpenState halfOpen = new HalfOpenState();
56          private ClosedState closed = new ClosedState();          private final ClosedState closed = new ClosedState();
57                    
58          private String name;          private String name;
59                    
60          public CircuitBreaker(String name, int threshold, long timeoutMS) {          private ExecutorService executor = null;        
61                  closed.setThreshold(threshold);          private Notifier notifier = new NullNotifier();
62                  open.setTimeout(timeoutMS);          
63            public CircuitBreaker(String name, int threshold, int timeoutMS) {
64                    this(name, new StaticConfig(threshold, timeoutMS) );
65            }
66            
67            public CircuitBreaker(String name, BreakerConfig config) {
68                    closed.setThreshold(config);
69                    open.setTimeout(config);
70                                    
71                  this.name = name;                  this.name = name;
72                            
73                  reset();                  //set correct intial state
74                    internalReset();
75            }
76            
77            public synchronized void shutdown() {
78                    if (executor != null) {
79                            executor.shutdown();
80                    }
81          }          }
82                    
83                    
84      public Object invoke(CircuitInvocation invocation) throws Throwable      public Object invoke(CircuitInvocation invocation) throws Exception
85      {      {
86          Object result = null;          Object result = null;
87          try          try
# Line 68  public class CircuitBreaker{ Line 90  public class CircuitBreaker{
90              result = invocation.proceed();              result = invocation.proceed();
91              getState().postInvoke(this);              getState().postInvoke(this);
92          }          }
93          catch(Throwable t)          catch(Exception e)
94          {          {
95              getState().onError(this, t);              getState().onError(this, e);
96              throw t;              throw e;
97          }          }
98          return result;          return result;
99      }      }
100            
101      public void tripBreaker() {      public void tripBreaker() {
102          synchronized(this) {          commonTripBreaker(Notifier.Event.BreakerTripped);
103                  currentState = open;      }
                 open.trip();  
                   
                 logger.warning("Circuitbreaker tripBreaker - " + name);  
         }  
104            
105            //a re-trip should basically do the same as a normal trip, but it is here just to differentiate the two different events
106        public void retripBreaker() {
107            commonTripBreaker(Notifier.Event.BreakerRetripped);
108      }      }
109            
110        private void commonTripBreaker(Notifier.Event event) {
111            synchronized(this) {
112                    if (currentState != open) { // TODO:Is this conditional necessary ??
113                            open.trip();
114                            currentState = open;
115                    
116                            notifier.sendNotification(this, event);
117                    }
118            }      
119        }
120    
121      public void attemptReset() {      public void attemptReset() {
122          synchronized(this) {          synchronized(this) {
123                  currentState = halfOpen;                  if (currentState != halfOpen) { // TODO:Is this conditional necessary ??
124                                            currentState = halfOpen;
125                  logger.warning("Circuitbreaker attemptReset - " + name);                          notifier.sendNotification(this, Notifier.Event.BreakerAttemptReset);
126                    }
127          }          }
128            
129      }      }
130            
131      public void reset() {      public void reset() {
132          synchronized(this) {          synchronized(this) {
133                  currentState = closed;                  if (currentState != closed) { // TODO: Is this conditional necessary ??
134                                            internalReset();
135                  logger.warning("Circuitbreaker reset - " + name);                          notifier.sendNotification(this, Notifier.Event.BreakerReset);
136                    }
137          }          }
138      }      }
139            
140        //This one actually sets the correct closed/reset state
141        private void internalReset() {
142                    closed.resetFailureCount();
143                    currentState = closed;          
144        }
145        
146        
147      private CircuitBreakerState getState() {      private CircuitBreakerState getState() {
148          synchronized(this) {          synchronized(this) {
149                  return currentState;                  return currentState;
150          }          }
151      }      }
152        
153        public boolean isClosed() {
154            return (getState() == closed);
155        }
156        
157        public boolean isOpen() {
158            return (getState() == open);
159        }
160        
161        public String getName() {
162            return name;
163        }
164        
165        public String getStateName() {
166            return getState().getName();
167        }
168        
169        public int getThreshold() {
170            return closed.getThreshold();
171        }
172        
173        public int getTimeout() {
174            return (int)open.getTimeout();
175        }
176        
177        public int getFailureCount() {
178            if (getState() == closed) {
179                    return closed.getFailureCount();
180            } else {
181                    return -1;
182            }
183        }
184        
185        public long getElapsed() {
186            if (getState() == open) {
187                    return open.getElapsed();
188            } else {
189                    return -1;
190            }
191        }
192        
193        public void setNotifier(Notifier notifier) {
194            this.notifier = notifier;
195        }
196        
197        public String getNotifierName() {
198            return NotiferHelper.getName(notifier);
199        }
200        
201        public synchronized ExecutorService getExecutor() {
202            
203            if (executor == null) {
204                    executor = Executors.newFixedThreadPool(1);
205            }
206            
207            return executor;
208            
209        }
210    
211  }  }

Legend:
Removed from v.394  
changed lines
  Added in v.1306

  ViewVC Help
Powered by ViewVC 1.1.20