1 5 package com.tc.cluster; 6 7 import com.tc.logging.TCLogger; 8 import com.tc.logging.TCLogging; 9 10 import java.util.Arrays ; 11 import java.util.HashMap ; 12 import java.util.IdentityHashMap ; 13 import java.util.Iterator ; 14 import java.util.Map ; 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 nodes = new HashMap (); private final IdentityHashMap listeners = new IdentityHashMap (); 24 private Node thisNode; 25 26 public synchronized Node getThisNode() { 27 return thisNode; 28 } 29 30 Map getNodes() { 32 return nodes; 33 } 34 35 public synchronized void thisNodeConnected(final String thisNodeId, String [] nodesCurrentlyInCluster) { 36 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 return; 56 } 57 fireThisNodeDisconnectedEvent(); 58 nodes.clear(); 59 thisNode = null; 60 } 61 62 public synchronized void nodeConnected(String nodeId) { 63 Node n = new Node(nodeId); 64 65 if (n.equals(thisNode)) { throw new AssertionError ("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 nodeId) { 74 nodes.remove(nodeId); 75 debug("### Cluster: nodeDisconnected -> " + this); 76 fireNodeDisconnectedEvent(nodeId); 77 } 78 79 public synchronized String toString() { 80 return "Cluster{ thisNode=" + thisNode + ", nodesInCluster=" + nodes.keySet() + "}"; 82 } 83 84 public synchronized void addClusterEventListener(ClusterEventListener cel) { 85 assertPre(thisNode != null); 87 88 Object oldCel = listeners.put(cel, cel); 89 if (oldCel == null) { 90 fireThisNodeConnectedEvent(cel, getCurrentNodeIds()); 91 } 92 } 93 94 private void fireThisNodeConnectedEvent(ClusterEventListener cel, String [] ids) { 95 try { 96 cel.thisNodeConnected(thisNode.getNodeId(), ids); 97 } catch (Throwable t) { 98 log(t); 99 } 100 } 101 102 private void fireThisNodeConnectedEvent() { 103 assertPre(thisNode != null); 104 final String ids[] = getCurrentNodeIds(); 105 for (Iterator 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 i = listeners.keySet().iterator(); i.hasNext();) { 113 ClusterEventListener l = (ClusterEventListener) i.next(); 114 try { 115 l.thisNodeDisconnected(thisNode.getNodeId()); 116 } catch (Throwable t) { 117 log(t); 118 } 119 } 120 } 121 122 private void fireNodeConnectedEvent(String newNodeId) { 123 if (thisNode == null) { return; } 124 for (Iterator i = listeners.keySet().iterator(); i.hasNext();) { 125 ClusterEventListener l = (ClusterEventListener) i.next(); 126 try { 127 l.nodeConnected(newNodeId); 128 } catch (Throwable t) { 129 log(t); 130 } 131 } 132 } 133 134 private void fireNodeDisconnectedEvent(String nodeId) { 135 if (thisNode == null) { return; } 136 for (Iterator i = listeners.keySet().iterator(); i.hasNext();) { 137 ClusterEventListener l = (ClusterEventListener) i.next(); 138 try { 139 l.nodeDisconnected(nodeId); 140 } catch (Throwable t) { 141 log(t); 142 } 143 } 144 } 145 146 private static void assertPre(boolean b) { 147 if (!b) throw new AssertionError ("Pre-condition failed!"); 148 } 149 150 private String [] getCurrentNodeIds() { 151 final String [] rv = new String [nodes.size()]; 152 nodes.keySet().toArray(rv); 153 Arrays.sort(rv); 154 return rv; 155 } 156 157 private static void debug(String string) { 158 if (debug) System.err.println(string); 159 } 160 161 private void log(Throwable t) { 162 logger.error("Unhandled exception in event callback " + this, t); 163 } 164 } 165 | Popular Tags |