KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > cluster > Cluster


1 /*
2  * All content copyright (c) 2003-2007 Terracotta, Inc., except as may otherwise be noted in a separate copyright
3  * notice. All rights reserved.
4  */

5 package com.tc.cluster;
6
7 import com.tc.logging.TCLogger;
8 import com.tc.logging.TCLogging;
9
10 import java.util.Arrays JavaDoc;
11 import java.util.HashMap JavaDoc;
12 import java.util.IdentityHashMap JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.Map JavaDoc;
15
16 public class Cluster {
17
18   private static final TCLogger logger = TCLogging.getLogger(Cluster.class);
19   private static final boolean debug = false;
20
21   private final Map JavaDoc nodes = new HashMap JavaDoc(); // <String, Node>
22
private final IdentityHashMap JavaDoc listeners = new IdentityHashMap JavaDoc(); // <ClusterEventListener>
23

24   private Node thisNode;
25
26   public synchronized Node getThisNode() {
27     return thisNode;
28   }
29
30   // for tests
31
Map JavaDoc getNodes() {
32     return nodes;
33   }
34
35   public synchronized void thisNodeConnected(final String JavaDoc thisNodeId, String JavaDoc[] nodesCurrentlyInCluster) {
36     // we might get multiple calls in a row, ignore all but the first in a row.
37
if (thisNode != null) return;
38
39     thisNode = new Node(thisNodeId);
40     nodes.put(thisNode.getNodeId(), thisNode);
41
42     for (int i = 0; i < nodesCurrentlyInCluster.length; i++) {
43       Node n = new Node(nodesCurrentlyInCluster[i]);
44       nodes.put(n.getNodeId(), n);
45     }
46
47     debug("### Cluster: thisNodeConnected -> " + this);
48     fireThisNodeConnectedEvent();
49   }
50
51   public synchronized void thisNodeDisconnected() {
52     debug("### Cluster: thisNodeDisconnected -> " + this);
53     if (thisNode == null) {
54       // client channels be closed before we know thisNodeID. Skip the disconnect event in this case
55
return;
56     }
57     fireThisNodeDisconnectedEvent();
58     nodes.clear();
59     thisNode = null;
60   }
61
62   public synchronized void nodeConnected(String JavaDoc nodeId) {
63     Node n = new Node(nodeId);
64
65     // the server should not be sending this event to us
66
if (n.equals(thisNode)) { throw new AssertionError JavaDoc("received message for self"); }
67
68     nodes.put(n.getNodeId(), n);
69     debug("### Cluster: nodeConnected -> " + this);
70     fireNodeConnectedEvent(nodeId);
71   }
72
73   public synchronized void nodeDisconnected(String JavaDoc nodeId) {
74     nodes.remove(nodeId);
75     debug("### Cluster: nodeDisconnected -> " + this);
76     fireNodeDisconnectedEvent(nodeId);
77   }
78
79   public synchronized String JavaDoc toString() {
80     // NOTE: this method is used in the error logging
81
return "Cluster{ thisNode=" + thisNode + ", nodesInCluster=" + nodes.keySet() + "}";
82   }
83
84   public synchronized void addClusterEventListener(ClusterEventListener cel) {
85     // If this assertion is going off, you're (probably) trying to add your listener too early
86
assertPre(thisNode != null);
87
88     Object JavaDoc oldCel = listeners.put(cel, cel);
89     if (oldCel == null) {
90       fireThisNodeConnectedEvent(cel, getCurrentNodeIds());
91     }
92   }
93
94   private void fireThisNodeConnectedEvent(ClusterEventListener cel, String JavaDoc[] ids) {
95     try {
96       cel.thisNodeConnected(thisNode.getNodeId(), ids);
97     } catch (Throwable JavaDoc t) {
98       log(t);
99     }
100   }
101
102   private void fireThisNodeConnectedEvent() {
103     assertPre(thisNode != null);
104     final String JavaDoc ids[] = getCurrentNodeIds();
105     for (Iterator JavaDoc i = listeners.keySet().iterator(); i.hasNext();) {
106       ClusterEventListener l = (ClusterEventListener) i.next();
107       fireThisNodeConnectedEvent(l, ids);
108     }
109   }
110
111   private void fireThisNodeDisconnectedEvent() {
112     for (Iterator JavaDoc i = listeners.keySet().iterator(); i.hasNext();) {
113       ClusterEventListener l = (ClusterEventListener) i.next();
114       try {
115         l.thisNodeDisconnected(thisNode.getNodeId());
116       } catch (Throwable JavaDoc t) {
117         log(t);
118       }
119     }
120   }
121
122   private void fireNodeConnectedEvent(String JavaDoc newNodeId) {
123     if (thisNode == null) { return; }
124     for (Iterator JavaDoc i = listeners.keySet().iterator(); i.hasNext();) {
125       ClusterEventListener l = (ClusterEventListener) i.next();
126       try {
127         l.nodeConnected(newNodeId);
128       } catch (Throwable JavaDoc t) {
129         log(t);
130       }
131     }
132   }
133
134   private void fireNodeDisconnectedEvent(String JavaDoc nodeId) {
135     if (thisNode == null) { return; }
136     for (Iterator JavaDoc i = listeners.keySet().iterator(); i.hasNext();) {
137       ClusterEventListener l = (ClusterEventListener) i.next();
138       try {
139         l.nodeDisconnected(nodeId);
140       } catch (Throwable JavaDoc t) {
141         log(t);
142       }
143     }
144   }
145
146   private static void assertPre(boolean b) {
147     if (!b) throw new AssertionError JavaDoc("Pre-condition failed!");
148   }
149
150   private String JavaDoc[] getCurrentNodeIds() {
151     final String JavaDoc[] rv = new String JavaDoc[nodes.size()];
152     nodes.keySet().toArray(rv);
153     Arrays.sort(rv);
154     return rv;
155   }
156
157   private static void debug(String JavaDoc string) {
158     if (debug) System.err.println(string);
159   }
160
161   private void log(Throwable JavaDoc t) {
162     logger.error("Unhandled exception in event callback " + this, t);
163   }
164 }
165
Popular Tags