From ea501d7083cb3fb98c01871a756f2036e31d69e3 Mon Sep 17 00:00:00 2001 From: Michael Bayne Date: Tue, 31 Jul 2007 20:01:52 +0000 Subject: [PATCH] Automatically register the peer manager as a shutdowner rather than require that it be shut down manually. git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@4794 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../presents/peer/server/PeerManager.java | 184 +++++++++--------- 1 file changed, 91 insertions(+), 93 deletions(-) diff --git a/src/java/com/threerings/presents/peer/server/PeerManager.java b/src/java/com/threerings/presents/peer/server/PeerManager.java index f6e93a8d0..2c2415158 100644 --- a/src/java/com/threerings/presents/peer/server/PeerManager.java +++ b/src/java/com/threerings/presents/peer/server/PeerManager.java @@ -71,7 +71,7 @@ import static com.threerings.presents.Log.log; * servers and uses those objects to communicate cross-node information. */ public class PeerManager - implements PeerProvider, ClientManager.ClientObserver + implements PeerProvider, ClientManager.ClientObserver, PresentsServer.Shutdowner { /** * Used by entities that wish to know when cached data has become stale due to a change on @@ -117,7 +117,7 @@ public class PeerManager { /** * Called when the resource lock was acquired successfully. The lock will be released - * immediately after this function call finishes. + * immediately after this function call finishes. */ public void run (); @@ -127,7 +127,7 @@ public class PeerManager */ public void fail (String peerName); } - + /** * Creates a peer manager which will create a {@link NodeRepository} which will be used to * publish our existence and discover the other nodes. @@ -136,6 +136,7 @@ public class PeerManager { _invoker = invoker; _noderepo = new NodeRepository(ctx); + PresentsServer.registerShutdowner(this); } /** @@ -213,39 +214,6 @@ public class PeerManager didInit(); } - /** - * Call this when the server is shutting down to give this node a chance to cleanly logoff from - * its peers and remove its record from the nodes table. - */ - public void shutdown () - { - // clear out our invocation service - if (_nodeobj != null) { - PresentsServer.invmgr.clearDispatcher(_nodeobj.peerService); - } - - // clear out our client observer registration - PresentsServer.clmgr.removeClientObserver(this); - - // clear our record from the node table - _invoker.postUnit(new Invoker.Unit("deleteNode") { - public boolean invoke () { - try { - _noderepo.deleteNode(_nodeName); - } catch (PersistenceException pe) { - log.warning("Failed to delete node record [nodeName=" + _nodeName + - ", error=" + pe + "]."); - } - return false; - } - }); - - // shut down the peers - for (PeerNode peer : _peers.values()) { - peer.shutdown(); - } - } - /** * Locates the client with the specified name. Returns null if the client is not logged onto * any peer. @@ -529,7 +497,7 @@ public class PeerManager /** * Tries to acquire the resource lock and, if successful, performs the operation and releases * the lock; if unsuccessful, calls the operation's failure handler. Please note: the lock will - * be released immediately after the operation. + * be released immediately after the operation. */ public void performWithLock (final NodeObject.Lock lock, final LockedOperation operation) { @@ -570,62 +538,6 @@ public class PeerManager _dropobs.remove(observer); } - // documentation inherited from interface PeerProvider - public void ratifyLockAction (ClientObject caller, NodeObject.Lock lock, boolean acquire) - { - LockHandler handler = _locks.get(lock); - if (handler != null && handler.getNodeName().equals(_nodeName)) { - handler.ratify(caller, acquire); - } else { - // this is not an error condition, as we may have cancelled the handler or - // allowed another to take priority - } - } - - // documentation inherited from interface ClientManager.ClientObserver - public void clientSessionDidStart (PresentsClient client) - { - // if this is another peer, don't publish their info - if (client instanceof PeerClient) { - return; - } - - // create and publish a ClientInfo record for this client - ClientInfo clinfo = createClientInfo(); - initClientInfo(client, clinfo); - - // sanity check - if (_nodeobj.clients.contains(clinfo)) { - log.warning("Received clientSessionDidStart() for already registered client!? " + - "[old=" + _nodeobj.clients.get(clinfo.getKey()) + ", new=" + clinfo + "]."); - // go ahead and update the record - _nodeobj.updateClients(clinfo); - } else { - _nodeobj.addToClients(clinfo); - } - } - - // documentation inherited from interface ClientManager.ClientObserver - public void clientSessionDidEnd (PresentsClient client) - { - // if this is another peer, don't worry about it - if (client instanceof PeerClient) { - return; - } - - // we scan through the list instead of relying on ClientInfo.getKey() because we want - // derived classes to be able to override that for lookups that happen way more frequently - // than logging off - Name username = client.getCredentials().getUsername(); - for (ClientInfo clinfo : _nodeobj.clients) { - if (clinfo.username.equals(username)) { - clearClientInfo(client, clinfo); - return; - } - } - log.warning("Session ended for unregistered client [who=" + username + "]."); - } - /** * Called by {@link PeerClient}s when clients subscribe to the {@link NodeObject}. */ @@ -683,6 +595,92 @@ public class PeerManager _nodeobj.setCacheData(new NodeObject.CacheData(cache, data)); } + // from interface PresentsServer.Shutdowner + public void shutdown () + { + // clear out our invocation service + if (_nodeobj != null) { + PresentsServer.invmgr.clearDispatcher(_nodeobj.peerService); + } + + // clear out our client observer registration + PresentsServer.clmgr.removeClientObserver(this); + + // clear our record from the node table + _invoker.postUnit(new Invoker.Unit("deleteNode") { + public boolean invoke () { + try { + _noderepo.deleteNode(_nodeName); + } catch (PersistenceException pe) { + log.warning("Failed to delete node record [nodeName=" + _nodeName + + ", error=" + pe + "]."); + } + return false; + } + }); + + // shut down the peers + for (PeerNode peer : _peers.values()) { + peer.shutdown(); + } + } + + // from interface PeerProvider + public void ratifyLockAction (ClientObject caller, NodeObject.Lock lock, boolean acquire) + { + LockHandler handler = _locks.get(lock); + if (handler != null && handler.getNodeName().equals(_nodeName)) { + handler.ratify(caller, acquire); + } else { + // this is not an error condition, as we may have cancelled the handler or + // allowed another to take priority + } + } + + // from interface ClientManager.ClientObserver + public void clientSessionDidStart (PresentsClient client) + { + // if this is another peer, don't publish their info + if (client instanceof PeerClient) { + return; + } + + // create and publish a ClientInfo record for this client + ClientInfo clinfo = createClientInfo(); + initClientInfo(client, clinfo); + + // sanity check + if (_nodeobj.clients.contains(clinfo)) { + log.warning("Received clientSessionDidStart() for already registered client!? " + + "[old=" + _nodeobj.clients.get(clinfo.getKey()) + ", new=" + clinfo + "]."); + // go ahead and update the record + _nodeobj.updateClients(clinfo); + } else { + _nodeobj.addToClients(clinfo); + } + } + + // from interface ClientManager.ClientObserver + public void clientSessionDidEnd (PresentsClient client) + { + // if this is another peer, don't worry about it + if (client instanceof PeerClient) { + return; + } + + // we scan through the list instead of relying on ClientInfo.getKey() because we want + // derived classes to be able to override that for lookups that happen way more frequently + // than logging off + Name username = client.getCredentials().getUsername(); + for (ClientInfo clinfo : _nodeobj.clients) { + if (clinfo.username.equals(username)) { + clearClientInfo(client, clinfo); + return; + } + } + log.warning("Session ended for unregistered client [who=" + username + "]."); + } + /** * Called after we have finished our initialization. */