/[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 409 by torben, Wed Oct 7 07:07:00 2009 UTC miscJava/CircuitBreaker/src/main/java/dk/thoerup/circuitbreaker/CircuitBreaker.java revision 3212 by torben, Thu Dec 28 09:34:47 2017 UTC
# Line 1  Line 1 
1  package dk.thoerup.curcuitbreaker;  package dk.thoerup.circuitbreaker;
2    
 import java.util.logging.Logger;  
3    
4  import dk.thoerup.curcuitbreaker.notification.Notifier;  import java.util.concurrent.ExecutorService;
5  import dk.thoerup.curcuitbreaker.notification.NullNotifier;  import java.util.concurrent.Executors;
6    
7    import dk.thoerup.circuitbreaker.config.BreakerConfig;
8    import dk.thoerup.circuitbreaker.notification.NotiferHelper;
9    import dk.thoerup.circuitbreaker.notification.Notifier;
10    import dk.thoerup.circuitbreaker.notification.NullNotifier;
11    import dk.thoerup.circuitbreaker.statistics.NullStatistics;
12    import dk.thoerup.circuitbreaker.statistics.Statistics;
13    
14  /* 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
15   *   *
16   *  example of how it can be used   *  example of how it can be used
17    
18   private CircuitBreaker cb = new CircuitBreaker("test", 5, 10000);   private CircuitBreaker<String> cb = new CircuitBreaker<>("test", 5, 10000);
19   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {   protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
20                  class TestInvocation implements CircuitInvocation {                  class TestInvocation implements CircuitInvocation<String> {
21                          String url;                          String url;
22                          public TestInvocation(String url) {                          public TestInvocation(String url) {
23                                  this.url = url;                                  this.url = url;
24                          }                          }
25                          public Object proceed() throws Exception{                          public String proceed() throws Exception{
26                                                                    
27                                  URL u = new URL(url);                                  URL u = new URL(url);
28                                  URLConnection c = u.openConnection();                                  URLConnection c = u.openConnection();
# Line 30  import dk.thoerup.curcuitbreaker.notific Line 36  import dk.thoerup.curcuitbreaker.notific
36                                                    
37                  }                  }
38                  try {                  try {
39                          String s = (String) cb.invoke(new TestInvocation("http://rafiki/test"));                          String s = cb.invoke(new TestInvocation("http://rafiki/test"));
40                          response.getWriter().print(s);                          response.getWriter().print(s);
41                  } catch (Throwable e) {                  } catch (Exception e) {
42                          logger.warning( e.getMessage() );                          logger.warning( e.getMessage() );
43                          response.sendError(500);                          response.sendError(500);
44                          return;                          return;
# Line 42  import dk.thoerup.curcuitbreaker.notific Line 48  import dk.thoerup.curcuitbreaker.notific
48   */   */
49    
50    
51  public class CircuitBreaker{  public class CircuitBreaker<T>{
         Logger logger = Logger.getLogger(CircuitBreaker.class.getName());  
   
52                    
53          private CircuitBreakerState currentState;          private volatile CircuitBreakerState currentState;
54                    
55          private OpenState open = new OpenState();          private final OpenState open = new OpenState();
56          private HalfOpenState halfOpen = new HalfOpenState();          private final HalfOpenState halfOpen = new HalfOpenState();
57          private ClosedState closed = new ClosedState();          private final ClosedState closed = new ClosedState();
58                    
59          private String name;          private String name;
60                    
61            private ExecutorService executor = null;        
62          private Notifier notifier = new NullNotifier();          private Notifier notifier = new NullNotifier();
63            private Statistics stats = new NullStatistics();
64            
65                    
66          public CircuitBreaker(String name, int threshold, long timeoutMS) {          public CircuitBreaker(String name, BreakerConfig config) {
67                  closed.setThreshold(threshold);                  closed.setThreshold(config);
68                  open.setTimeout(timeoutMS);                  open.setTimeout(config);
69                                    
70                  this.name = name;                  this.name = name;
71                            
72                  reset();                  //set correct intial state
73                    internalReset();
74            }
75            
76            public synchronized void shutdown() {
77                    if (executor != null) {
78                            executor.shutdown();
79                    }
80          }          }
81                    
82                    
83      public Object invoke(CircuitInvocation invocation) throws Throwable      public T invoke(CircuitInvocation<T> invocation) throws Exception
84      {      {
85          Object result = null;          stats.addStatistics(Event.Invocation);
86            
87            T result = null;
88          try          try
89          {          {
90              getState().preInvoke(this);              getState().preInvoke(this);
91              result = invocation.proceed();              result = invocation.proceed();
92              getState().postInvoke(this);              getState().postInvoke(this);
93          }          }
94          catch(Throwable t)          catch(Exception e)
95          {          {              
96              getState().onError(this, t);                          if (e instanceof CircuitBreakerException) {
97              throw t;                                  stats.addStatistics(Event.InvocationBlocked);
98                            } else {
99                                    stats.addStatistics(Event.InvocationFailure);
100                            }
101                    
102                getState().onError(this, e);
103                throw e;
104          }          }
105          return result;          return result;
106      }      }
107            
108      public void tripBreaker() {      public void tripBreaker() {
109          synchronized(this) {          commonTripBreaker(Event.BreakerTripped);
110                  open.trip();      }
111                  currentState = open;      
112                            //a re-trip should basically do the same as a normal trip, but it is here just to differentiate the two different events
113                  notifier.sendNotification(name, Notifier.Event.BreakerTripped);      public void retripBreaker() {
114          }              commonTripBreaker(Event.BreakerRetripped);
115      }      }
116            
117        private void commonTripBreaker(Event event) {
118            synchronized(this) {
119                    if (currentState != open) { // TODO:Is this conditional necessary ??
120                            open.trip();
121                            currentState = open;
122                    
123                            notifier.sendNotification(this, event);
124                            stats.addStatistics(event);
125                    }
126            }      
127        }
128    
129      public void attemptReset() {      public void attemptReset() {
130          synchronized(this) {          synchronized(this) {
131                  currentState = halfOpen;                  if (currentState != halfOpen) { // TODO:Is this conditional necessary ??
132                  notifier.sendNotification(name, Notifier.Event.BreakerAttemptReset);                          currentState = halfOpen;
133                            notifier.sendNotification(this, Event.BreakerAttemptReset);
134                            stats.addStatistics(Event.BreakerAttemptReset);
135                    }
136          }          }
137                    
138      }      }
139            
140      public void reset() {      public void reset() {
141          synchronized(this) {          synchronized(this) {
142                  currentState = closed;                  if (currentState != closed) { // TODO: Is this conditional necessary ??
143                  notifier.sendNotification(name, Notifier.Event.BreakerReset);                          internalReset();
144                            notifier.sendNotification(this, Event.BreakerReset);
145                            stats.addStatistics(Event.BreakerReset);
146                    }
147          }          }
148      }      }
149            
150        //This one actually sets the correct closed/reset state
151        private void internalReset() {
152                    closed.resetFailureCount();
153                    currentState = closed;          
154        }
155        
156            
157      private CircuitBreakerState getState() {      private CircuitBreakerState getState() {
158          synchronized(this) {          synchronized(this) {
# Line 114  public class CircuitBreaker{ Line 160  public class CircuitBreaker{
160          }          }
161      }      }
162            
163        public boolean isClosed() {
164            return (getState() == closed);
165        }
166        
167        public boolean isOpen() {
168            return (getState() == open);
169        }
170        
171      public String getName() {      public String getName() {
172          return name;          return name;
173      }      }
# Line 126  public class CircuitBreaker{ Line 180  public class CircuitBreaker{
180          return closed.getThreshold();          return closed.getThreshold();
181      }      }
182            
183        public int getTimeout() {
184            return (int)open.getTimeout();
185        }
186        
187      public int getFailureCount() {      public int getFailureCount() {
188          if (getState() == closed) {          if (getState() == closed) {
189                  return closed.getFailureCount();                  return closed.getFailureCount();
# Line 143  public class CircuitBreaker{ Line 201  public class CircuitBreaker{
201      }      }
202            
203      public void setNotifier(Notifier notifier) {      public void setNotifier(Notifier notifier) {
204          this.notifier = notifier;          synchronized(this) {
205                    this.notifier = notifier;
206            }
207      }      }
208            
209      public String getNotifierName() {      public String getNotifierName() {
210          return notifier.toString();          return NotiferHelper.getName(notifier);
211        }
212        
213        public void setStatistics(Statistics newStats) {
214            this.stats = newStats;
215        }
216        
217        public Statistics getStatistics() {
218            return this.stats;
219        }
220        
221        public synchronized ExecutorService getExecutor() {
222            
223            if (executor == null) {
224                    executor = Executors.newFixedThreadPool(1);
225            }
226            
227            return executor;
228            
229      }      }
230    
231  }  }

Legend:
Removed from v.409  
changed lines
  Added in v.3212

  ViewVC Help
Powered by ViewVC 1.1.20