01: /*
02: @COPYRIGHT@
03: */
04: package demo.coordination;
05:
06: import java.text.MessageFormat;
07: import java.util.logging.Logger;
08:
09: import org.springframework.beans.factory.DisposableBean;
10: import org.springframework.beans.factory.InitializingBean;
11:
12: /**
13: * Simple service using process coordination via synchronization.
14: */
15: public class CounterService implements InitializingBean,
16: DisposableBean, Runnable {
17: private static final Logger logger = Logger
18: .getLogger(CounterService.class.getName());
19:
20: private static final String LOG_PREFIX = System.getProperty(
21: "counter.log.prefix", "Counter service [INFO]:")
22: + " ";
23: private static final int MAX_COUNTER = 999;
24: private static final String STATUS_FORMAT = "This node is currently <font color=\"green\"><b><i>{0}</i></b></font>.<br>The current distributed counter value is: {1}";
25:
26: // By making this variables transient, Terracotta for Spring will *not* cluster it
27: private transient boolean running;
28:
29: // These objects are distributed by Terracotta for Spring
30: private int counter = 0;
31: private final Object lock = new Object();
32:
33: public void afterPropertiesSet() throws Exception {
34: log("Creating background thread to try to increment counter");
35: Thread t = new Thread(this , "MessageService");
36: t.start();
37: }
38:
39: public void destroy() throws Exception {
40: running = false;
41: }
42:
43: public void run() {
44: log("[background thread] Waiting to synchronize on the counter lock...");
45: synchronized (lock) {
46: log("[background thread] Got the counter lock, I will start incrementing the counter");
47: running = true;
48: boolean logFirstIncrement = true;
49: while (running) {
50: synchronized (this ) {
51: counter++;
52: if (counter > MAX_COUNTER)
53: counter = 0;
54: if (logFirstIncrement) {
55: log("[background thread] Incremented the counter to "
56: + counter
57: + " -- will increment every second");
58: logFirstIncrement = false;
59: }
60: }
61: try {
62: Thread.sleep(1000L);
63: } catch (InterruptedException ex) {
64: // Ignore and keep processing
65: }
66: }
67: }
68: }
69:
70: public String getStatus() {
71: synchronized (this ) {
72: return MessageFormat.format(STATUS_FORMAT, new Object[] {
73: running ? "active" : "passive",
74: new Integer(counter) });
75: }
76: }
77:
78: private static void log(String message) {
79: logger.info(LOG_PREFIX + message);
80: }
81:
82: }
|