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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1148 - (hide annotations) (download)
Fri Oct 1 11:40:30 2010 UTC (13 years, 8 months ago) by torben
Original Path: CircuitBreaker/src/dk/thoerup/circuitbreaker/CircuitBreaker.java
File size: 4827 byte(s)
Support for async notifiers (and basic java notifier - needs debugging)
1 torben 467 package dk.thoerup.circuitbreaker;
2 torben 393
3    
4 torben 1148 import java.util.concurrent.ExecutorService;
5     import java.util.concurrent.Executors;
6    
7 torben 467 import dk.thoerup.circuitbreaker.notification.Notifier;
8     import dk.thoerup.circuitbreaker.notification.NullNotifier;
9 torben 409
10 torben 394 /* Simple CircuitBreaker implementation - snipped from http://www.jroller.com/kenwdelong/entry/circuit_breaker_in_java
11     *
12     * example of how it can be used
13 torben 395
14     private CircuitBreaker cb = new CircuitBreaker("test", 5, 10000);
15     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
16 torben 393 class TestInvocation implements CircuitInvocation {
17     String url;
18     public TestInvocation(String url) {
19     this.url = url;
20     }
21     public Object proceed() throws Exception{
22    
23     URL u = new URL(url);
24     URLConnection c = u.openConnection();
25     c.connect();
26     InputStream in = c.getInputStream();
27     in.close();
28    
29    
30     return "hello";
31     }
32    
33     }
34     try {
35     String s = (String) cb.invoke(new TestInvocation("http://rafiki/test"));
36     response.getWriter().print(s);
37 torben 452 } catch (Exception e) {
38 torben 393 logger.warning( e.getMessage() );
39     response.sendError(500);
40     return;
41     }
42    
43     }
44     */
45    
46    
47     public class CircuitBreaker{
48    
49 torben 443 private volatile CircuitBreakerState currentState;
50 torben 393
51 torben 424 private final OpenState open = new OpenState();
52     private final HalfOpenState halfOpen = new HalfOpenState();
53     private final ClosedState closed = new ClosedState();
54 torben 393
55     private String name;
56    
57 torben 1148 private ExecutorService executor = null;
58 torben 409 private Notifier notifier = new NullNotifier();
59    
60 torben 393 public CircuitBreaker(String name, int threshold, long timeoutMS) {
61     closed.setThreshold(threshold);
62     open.setTimeout(timeoutMS);
63    
64     this.name = name;
65 torben 625
66 torben 627 //set correct intial state
67     internalReset();
68 torben 393 }
69    
70 torben 1148 public synchronized void shutdown() {
71     if (executor != null) {
72     executor.shutdown();
73     }
74     }
75 torben 393
76 torben 1148
77 torben 450 public Object invoke(CircuitInvocation invocation) throws Exception
78 torben 393 {
79     Object result = null;
80     try
81     {
82     getState().preInvoke(this);
83     result = invocation.proceed();
84     getState().postInvoke(this);
85     }
86 torben 450 catch(Exception e)
87 torben 393 {
88 torben 450 getState().onError(this, e);
89     throw e;
90 torben 393 }
91     return result;
92     }
93    
94     public void tripBreaker() {
95 torben 871 commonTripBreaker(Notifier.Event.BreakerTripped);
96 torben 393 }
97    
98 torben 864 //a re-trip should basically do the same as a normal trip, but it is here just to differentiate the two different events
99     public void retripBreaker() {
100 torben 871 commonTripBreaker(Notifier.Event.BreakerRetripped);
101     }
102    
103     private void commonTripBreaker(Notifier.Event event) {
104     synchronized(this) {
105 torben 864 if (currentState != open) { // TODO:Is this conditional necessary ??
106     open.trip();
107     currentState = open;
108    
109 torben 871 notifier.sendNotification(name, event);
110 torben 864 }
111 torben 871 }
112 torben 864 }
113    
114 torben 393 public void attemptReset() {
115     synchronized(this) {
116 torben 426 if (currentState != halfOpen) { // TODO:Is this conditional necessary ??
117     currentState = halfOpen;
118     notifier.sendNotification(name, Notifier.Event.BreakerAttemptReset);
119     }
120 torben 393 }
121 torben 409
122 torben 393 }
123    
124     public void reset() {
125     synchronized(this) {
126 torben 426 if (currentState != closed) { // TODO: Is this conditional necessary ??
127 torben 627 internalReset();
128 torben 426 notifier.sendNotification(name, Notifier.Event.BreakerReset);
129     }
130 torben 393 }
131     }
132    
133 torben 627 //This one actually sets the correct closed/reset state
134     private void internalReset() {
135     closed.resetFailureCount();
136     currentState = closed;
137     }
138 torben 397
139 torben 627
140 torben 393 private CircuitBreakerState getState() {
141     synchronized(this) {
142     return currentState;
143     }
144     }
145 torben 397
146 torben 447 public boolean isClosed() {
147     return (getState() == closed);
148     }
149    
150     public boolean isOpen() {
151     return (getState() == open);
152     }
153    
154 torben 397 public String getName() {
155     return name;
156     }
157    
158     public String getStateName() {
159     return getState().getName();
160     }
161    
162     public int getThreshold() {
163     return closed.getThreshold();
164     }
165    
166 torben 413 public int getTimeout() {
167     return (int)open.getTimeout();
168     }
169    
170 torben 397 public int getFailureCount() {
171     if (getState() == closed) {
172     return closed.getFailureCount();
173     } else {
174     return -1;
175     }
176     }
177    
178     public long getElapsed() {
179     if (getState() == open) {
180     return open.getElapsed();
181     } else {
182     return -1;
183     }
184     }
185 torben 409
186     public void setNotifier(Notifier notifier) {
187     this.notifier = notifier;
188     }
189    
190     public String getNotifierName() {
191 torben 412 return notifier.getClass().getName();
192 torben 409 }
193 torben 1148
194     public synchronized ExecutorService getExecutor() {
195    
196     if (executor == null) {
197     executor = Executors.newFixedThreadPool(1);
198     }
199    
200     return executor;
201    
202     }
203 torben 397
204 torben 393 }

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20