1 package org.csc.phynixx.watchdog;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import org.apache.log4j.LogManager;
25 import org.apache.log4j.Logger;
26 import org.csc.phynixx.common.generator.IDGenerator;
27 import org.csc.phynixx.common.generator.IDGenerators;
28
29 import java.util.*;
30
31
32
33
34
35
36
37
38 public class WatchdogRegistry {
39
40
41 private static final IDGenerator<Long> ID_GENERATOR = IDGenerators.createLongGenerator(1, true);
42
43 private static final String WATCHDOG_MANAGEMENT_INTERVAL_PROP = "org.csc.phynixx.watchdog.management_interval";
44
45 public static final String OK = "ok";
46
47 private static long WATCHDOG_MANAGEMENT_INTERVAL = 1100;
48
49
50 private static WatchdogRegistry theRegistry = null;
51
52 public interface IWatchdogVisitor {
53 void visit(IWatchdog th);
54 }
55
56 private Watchdog watchTheWatchdogs = null;
57 private Watchdog watchTheWatchdogWatcher = null;
58
59
60 public static long getWatchdogManagementInterval() {
61 return WATCHDOG_MANAGEMENT_INTERVAL;
62 }
63
64 public static void setWatchdogManagementInterval(long watchdogManagementInterval) {
65 WatchdogRegistry.WATCHDOG_MANAGEMENT_INTERVAL = watchdogManagementInterval;
66
67
68 Set conditions = WatchdogRegistry.theRegistry.watchTheWatchdogs.getAliveConditions();
69 conditions.addAll(WatchdogRegistry.theRegistry.watchTheWatchdogWatcher.getAliveConditions());
70 for (Iterator iterator = conditions.iterator(); iterator.hasNext(); ) {
71 IWatchedCondition cond = (IWatchedCondition) iterator.next();
72 if (cond instanceof TimeoutCondition) {
73 TimeoutCondition toCond = (TimeoutCondition) cond;
74 synchronized (toCond) {
75 toCond.resetCondition(WatchdogRegistry.WATCHDOG_MANAGEMENT_INTERVAL);
76 }
77
78 }
79
80 }
81 }
82
83 public static long getWatchTheWatchdogInterval() {
84 return WATCHDOG_MANAGEMENT_INTERVAL;
85 }
86
87
88 static {
89 WatchdogRegistry.WATCHDOG_MANAGEMENT_INTERVAL = Long.getLong(WATCHDOG_MANAGEMENT_INTERVAL_PROP, 5000).longValue();
90
91 WatchdogRegistry.theRegistry = new WatchdogRegistry();
92 }
93
94 private WatchdogRegistry() {
95
96 this.watchTheWatchdogs = new Watchdog(ID_GENERATOR.generate(), WatchdogRegistry.getWatchdogManagementInterval() / 2, "Watches The Watchdogs");
97 this.watchTheWatchdogWatcher = new Watchdog(ID_GENERATOR.generate(), WatchdogRegistry.getWatchdogManagementInterval() / 2, "Watches The WatchdogWatcher");
98
99 IWatchedCondition watchesTheWatcherCond =
100 new RestartCondition(WatchdogRegistry.getWatchdogManagementInterval(), watchTheWatchdogs) {
101 public String toString() {
102 return new StringBuffer("watches the watchdog watcher ").
103 append("isActive=").append(this.isActive()).
104 append(" Watched WD.isAlive=").append(watchTheWatchdogs.isAlive()).
105 append(" Watched WD.isKilled=").append(watchTheWatchdogs.isKilled()).
106 toString();
107 }
108 };
109
110
111 watchesTheWatcherCond.setActive(true);
112 this.watchTheWatchdogWatcher.registerCondition(watchesTheWatcherCond, false);
113
114
115
116
117 IWatchedCondition managementActivity = new TimeoutCondition(WATCHDOG_MANAGEMENT_INTERVAL) {
118
119 public void conditionViolated() {
120 this.resetCondition();
121 WatchdogRegistry.getTheRegistry().clearOut();
122 }
123
124 };
125 managementActivity.setActive(true);
126 this.watchTheWatchdogWatcher.registerCondition(managementActivity, false);
127
128 this.restartManagementWatchdogs();
129
130 }
131
132
133
134
135
136 protected Logger log = LogManager.getLogger(this.getClass());
137
138
139
140
141 private Map registeredWachdogs = new HashMap();
142
143 private void checkManagementWatchdogs() {
144 if (watchTheWatchdogs == null || !watchTheWatchdogs.isAlive()) {
145 throw new IllegalStateException("WatchTheWatchdogs is not started -> call WatchdogRegistry.restart()");
146 }
147 if (watchTheWatchdogWatcher == null || !watchTheWatchdogWatcher.isAlive()) {
148 throw new IllegalStateException("WatchTheWatchdogWatcher is not started -> call WatchdogRegistry.restart()");
149 }
150 }
151
152 private void restartManagementWatchdogs() {
153
154 if (watchTheWatchdogs != null && (!watchTheWatchdogs.isAlive())) {
155 watchTheWatchdogs.restart();
156 watchTheWatchdogs.activate();
157 }
158 if (watchTheWatchdogWatcher != null && (!watchTheWatchdogWatcher.isAlive())) {
159 watchTheWatchdogWatcher.restart();
160 watchTheWatchdogWatcher.activate();
161 }
162 }
163
164 private void shutdownManagementWatchdogs() {
165
166
167 if (watchTheWatchdogs != null && (watchTheWatchdogs.isAlive())) {
168 watchTheWatchdogs.stop();
169 }
170 if (watchTheWatchdogWatcher != null && (watchTheWatchdogWatcher.isAlive())) {
171 watchTheWatchdogWatcher.stop();
172 }
173 }
174
175 public WatchdogInfo[] getManagementWatchdogsInfo() {
176
177 WatchdogInfo[] wds = new WatchdogInfo[2];
178 wds[0] = new WatchdogInfo(watchTheWatchdogs);
179 wds[1] = new WatchdogInfo(watchTheWatchdogWatcher);
180
181 return wds;
182 }
183
184 public synchronized String getManagementWatchdogsState() {
185 if (!watchTheWatchdogs.isAlive() || !watchTheWatchdogWatcher.isAlive()) {
186
187 return "Management Watchdogs aren't alive -> restart it";
188 }
189
190 return OK;
191 }
192
193 public synchronized IWatchdog createWatchdog(final long checkInterval) {
194
195 checkManagementWatchdogs();
196
197 Watchdog wd = new Watchdog(ID_GENERATOR.generate(), checkInterval);
198
199
200
201
202 IWatchedCondition restartCondition = wd.getRestartCondition();
203 restartCondition.setActive(true);
204
205 watchTheWatchdogs.registerCondition(restartCondition, true);
206
207 WatchdogRegistry.getTheRegistry().registerWatchdog(wd);
208
209 if (log.isDebugEnabled()) {
210 log.debug("Watchdog created \n" + wd);
211 log.debug(watchTheWatchdogs);
212 }
213
214 checkManagementWatchdogs();
215
216 return wd;
217 }
218
219
220 public static WatchdogRegistry getTheRegistry() {
221 return theRegistry;
222 }
223
224
225
226
227
228
229
230
231 private synchronized void registerWatchdog(Long key, Watchdog wd) {
232 if (wd == null) {
233 throw new NullPointerException("Thread");
234 }
235 if (wd.getThread() == null) {
236 wd.restart();
237 }
238 registeredWachdogs.put(key, wd);
239 }
240
241
242
243
244
245
246
247 public void registerWatchdog(Watchdog wd) {
248 registerWatchdog(wd.getId(), wd);
249 }
250
251 public synchronized void deregisterWatchdog(Long key) {
252 if (registeredWachdogs.containsKey(key)) {
253 registeredWachdogs.remove(key);
254 }
255 }
256
257 synchronized Watchdog findWatchdog(Long id) {
258 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
259 if (wd == null) {
260 return null;
261 }
262 return wd;
263 }
264
265 public synchronized IWatchdog resolveWatchdogId(Long id) {
266 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
267 if (wd == null) {
268 return null;
269 }
270 return new WatchdogReference(wd);
271 }
272
273
274 public void deregisterWatchdog(IWatchdog wd) {
275 deregisterWatchdog(wd.getId());
276 }
277
278
279 public synchronized void clearOut() {
280
281
282 Set copy = new HashSet(registeredWachdogs.values());
283 Iterator iter = copy.iterator();
284 while (iter.hasNext()) {
285 Watchdog wd = (Watchdog) iter.next();
286 if (wd.isUseless()) {
287 wd.kill();
288 this.deregisterWatchdog(wd);
289 if (log.isInfoEnabled()) {
290 log.info("WatchdogRegistry.restart() : Watchdog " + wd.getId() + " closed");
291 }
292 }
293 }
294
295 }
296
297
298
299
300 public synchronized void restart() {
301
302 restartManagementWatchdogs();
303
304 Set copy = new HashSet(registeredWachdogs.values());
305 Iterator iter = copy.iterator();
306 while (iter.hasNext()) {
307 Watchdog wd = (Watchdog) iter.next();
308 if (wd.isUseless()) {
309 wd.kill();
310 this.deregisterWatchdog(wd);
311 if (log.isInfoEnabled()) {
312 log.info("WatchdogRegistry.restart() : Watchdog " + wd.getId() + " closed");
313 }
314 } else if (!wd.isAlive() && !wd.isKilled()) {
315 wd.restart();
316 if (log.isInfoEnabled()) {
317 log.info("WatchdogRegistry.restart() : Watchdog " + wd.getId() + " restarted");
318 }
319 }
320 }
321
322 }
323
324
325
326
327 public synchronized void stop() {
328
329 Iterator iter = registeredWachdogs.values().iterator();
330 while (iter.hasNext()) {
331 Watchdog wd = (Watchdog) iter.next();
332 wd.stop();
333 if (log.isInfoEnabled()) {
334 log.info("WatchdogRegistry.stop() : Watchdog " + wd.getId() + " is stopped");
335 }
336 }
337
338
339 }
340
341
342
343
344 public synchronized void activate() {
345
346 Iterator iter = registeredWachdogs.values().iterator();
347
348 while (iter.hasNext()) {
349 IWatchdog th = (IWatchdog) iter.next();
350 th.activate();
351 if (log.isInfoEnabled()) {
352 log.info(". . . Activating Watchdog " + th.getId());
353 }
354 }
355 }
356
357
358
359
360 public synchronized void deactivate() {
361 Iterator iter = registeredWachdogs.values().iterator();
362 while (iter.hasNext()) {
363 IWatchdog th = (IWatchdog) iter.next();
364 th.deactivate();
365 if (log.isInfoEnabled()) {
366 log.info(". . . deactivating Watchdog " + th.getId());
367 }
368 }
369 }
370
371
372
373
374
375 private void kill() {
376 Set copy = new HashSet(registeredWachdogs.values());
377 Iterator iter = copy.iterator();
378 while (iter.hasNext()) {
379 Watchdog th = (Watchdog) iter.next();
380 if (th.isAlive()) {
381
382 if (log.isInfoEnabled()) {
383 log.info(". . . Killing Watchdog " + th.getId());
384 }
385 th.kill();
386 }
387 }
388
389 this.joinAllThreads();
390
391
392 iter = copy.iterator();
393 while (iter.hasNext()) {
394 this.deregisterWatchdog((IWatchdog) iter.next());
395 }
396 }
397
398
399
400
401
402
403 public synchronized void shutdown() {
404 this.shutdownManagementWatchdogs();
405
406
407 Iterator iter = registeredWachdogs.values().iterator();
408 while (iter.hasNext()) {
409 IWatchdog th = (IWatchdog) iter.next();
410 th.deactivate();
411 if (log.isInfoEnabled()) {
412 log.info(". . . Deactivating Watchdog " + th.getId());
413 }
414 }
415
416 this.kill();
417
418 }
419
420
421
422
423 private void joinAllThreads() {
424 Iterator iter = registeredWachdogs.values().iterator();
425 while (iter.hasNext()) {
426 Watchdog th = (Watchdog) iter.next();
427 boolean isJoining = true;
428 if (!th.isAlive() && log.isDebugEnabled()) {
429 log.debug("Thread " + th + " finished");
430 }
431 while (th.isAlive() && isJoining) {
432 try {
433 th.getThread().join();
434 isJoining = false;
435 if (log.isDebugEnabled()) {
436 log.debug("Thread " + th + " joined and finished");
437 }
438 } catch (InterruptedException e) {
439 }
440 }
441 }
442 }
443
444
445 public synchronized int getCountWatchdogs() {
446 return this.registeredWachdogs.size();
447 }
448
449
450 public WatchdogInfo[] getWatchdogInfos() {
451
452 final List watchdogs = new ArrayList();
453 WatchdogRegistry.IWatchdogVisitor visitor = new WatchdogRegistry.IWatchdogVisitor() {
454 public void visit(IWatchdog wd) {
455 watchdogs.add(new WatchdogInfo(wd));
456 }
457 };
458 this.visitWatchdogRegistry(visitor);
459
460 WatchdogInfo[] wds = new WatchdogInfo[watchdogs.size()];
461 int i = 0;
462 for (Iterator iterator = watchdogs.iterator(); iterator.hasNext(); i++) {
463 WatchdogInfo info = (WatchdogInfo) iterator.next();
464 wds[i] = info;
465 }
466 return wds;
467 }
468
469
470 public String[][] showWatchdogInfos() {
471
472 WatchdogInfo[] infos = this.getWatchdogInfos();
473 String[][] wds = new String[infos.length][];
474 for (int j = 0; j < infos.length; j++) {
475 wds[j] = infos[j].getWatchdogInfos();
476 }
477 return wds;
478
479 }
480
481
482
483
484
485 public synchronized void visitWatchdogRegistry(IWatchdogVisitor visitor) {
486 Iterator iter = registeredWachdogs.values().iterator();
487 while (iter.hasNext()) {
488 IWatchdog th = (IWatchdog) iter.next();
489 visitor.visit(th);
490 }
491
492 }
493
494
495
496
497
498
499
500
501
502
503
504
505 public void stop(Long id) {
506
507 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
508 if (wd == null) {
509 throw new IllegalStateException("Watchdog " + id + " ist not registered");
510 }
511 wd.stop();
512 }
513
514
515
516
517
518
519
520
521
522
523
524
525
526 public void shutdown(Long id) {
527
528 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
529 if (wd == null) {
530 throw new IllegalStateException("Watchdog " + id + " ist not registered");
531 }
532 wd.kill();
533 this.deregisterWatchdog(id);
534 }
535
536
537
538
539
540
541
542
543 public void restart(Long id) {
544
545 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
546 if (wd == null) {
547 throw new IllegalStateException("Watchdog " + id + " ist not registered");
548 }
549 wd.restart();
550 }
551
552
553
554
555
556
557
558 public void deactivate(Long id) {
559
560 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
561 if (wd == null) {
562 throw new IllegalStateException("Watchdog " + id + " ist not registered");
563 }
564 wd.deactivate();
565 }
566
567
568
569
570
571
572
573 public void activate(Long id) {
574
575 Watchdog wd = (Watchdog) this.registeredWachdogs.get(id);
576 if (wd == null) {
577 throw new IllegalStateException("Watchdog " + id + " ist not registered");
578 }
579 wd.activate();
580 }
581
582
583 }