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
This commit is contained in:
@@ -71,7 +71,7 @@ import static com.threerings.presents.Log.log;
|
|||||||
* servers and uses those objects to communicate cross-node information.
|
* servers and uses those objects to communicate cross-node information.
|
||||||
*/
|
*/
|
||||||
public class PeerManager
|
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
|
* 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
|
* 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 ();
|
public void run ();
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ public class PeerManager
|
|||||||
*/
|
*/
|
||||||
public void fail (String peerName);
|
public void fail (String peerName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a peer manager which will create a {@link NodeRepository} which will be used to
|
* Creates a peer manager which will create a {@link NodeRepository} which will be used to
|
||||||
* publish our existence and discover the other nodes.
|
* publish our existence and discover the other nodes.
|
||||||
@@ -136,6 +136,7 @@ public class PeerManager
|
|||||||
{
|
{
|
||||||
_invoker = invoker;
|
_invoker = invoker;
|
||||||
_noderepo = new NodeRepository(ctx);
|
_noderepo = new NodeRepository(ctx);
|
||||||
|
PresentsServer.registerShutdowner(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -213,39 +214,6 @@ public class PeerManager
|
|||||||
didInit();
|
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
|
* Locates the client with the specified name. Returns null if the client is not logged onto
|
||||||
* any peer.
|
* any peer.
|
||||||
@@ -529,7 +497,7 @@ public class PeerManager
|
|||||||
/**
|
/**
|
||||||
* Tries to acquire the resource lock and, if successful, performs the operation and releases
|
* 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
|
* 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)
|
public void performWithLock (final NodeObject.Lock lock, final LockedOperation operation)
|
||||||
{
|
{
|
||||||
@@ -570,62 +538,6 @@ public class PeerManager
|
|||||||
_dropobs.remove(observer);
|
_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}.
|
* 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));
|
_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.
|
* Called after we have finished our initialization.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user