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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:mergeinfo

  ViewVC Help
Powered by ViewVC 1.1.20