From 805372caf3a2158ec2383595b14bdbd4876603b6 Mon Sep 17 00:00:00 2001 From: Jamie Doornbos Date: Fri, 18 Jul 2008 00:06:06 +0000 Subject: [PATCH] Support bureau death * New static method to extract a bureau id from a username * Inject the client manager in the registry and tack all bureau sessions * Listen for sessions ending and call the clientDestroyed method * Actually clear our the agents and remove the bureau from the map when the client is destroyed (this will trigger a new launch for the next agent request in that bureau) * Deprecate addClientFactory * Added lookup function to retrieve a bureau session by bureau id so that client code will be able to kill specific bureau sessions git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5238 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../bureau/data/BureauCredentials.java | 20 ++++- .../bureau/server/BureauRegistry.java | 81 ++++++++++++++++++- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/java/com/threerings/bureau/data/BureauCredentials.java b/src/java/com/threerings/bureau/data/BureauCredentials.java index 5391c8b60..188cbf73b 100644 --- a/src/java/com/threerings/bureau/data/BureauCredentials.java +++ b/src/java/com/threerings/bureau/data/BureauCredentials.java @@ -29,6 +29,9 @@ import com.threerings.util.Name; */ public class BureauCredentials extends Credentials { + public static String PREFIX = "@@bureau:"; + public static String SUFFIX = "@@"; + /** * The token to pass to the server when logging in. This is usually just passed to the bureau * on the command line to guard against outside connections being established. @@ -46,7 +49,22 @@ public class BureauCredentials extends Credentials public static boolean isBureau (Name name) { String normal = name.getNormal(); - return normal.startsWith("@@bureau:") && normal.endsWith("@@"); + return normal.startsWith(PREFIX) && normal.endsWith(SUFFIX); + } + + /** + * Extract the buerauId from the name that we generate. + */ + public static String extractBureauId (Name name) + { + String normal = name.getNormal(); + int prefixPos = normal.indexOf(PREFIX); + int suffixPos = normal.lastIndexOf(SUFFIX); + if (prefixPos != 0 || suffixPos != normal.length() - SUFFIX.length()) { + return null; + } + + return normal.substring(prefixPos + PREFIX.length(), suffixPos); } /** diff --git a/src/java/com/threerings/bureau/server/BureauRegistry.java b/src/java/com/threerings/bureau/server/BureauRegistry.java index 2d9655452..41557eced 100644 --- a/src/java/com/threerings/bureau/server/BureauRegistry.java +++ b/src/java/com/threerings/bureau/server/BureauRegistry.java @@ -41,6 +41,7 @@ import com.threerings.presents.dobj.ObjectDestroyedEvent; import com.threerings.presents.dobj.RootDObjectManager; import com.threerings.presents.server.ClientManager; import com.threerings.presents.server.InvocationManager; +import com.threerings.presents.server.PresentsClient; import com.threerings.bureau.data.AgentObject; import com.threerings.bureau.data.BureauCodes; @@ -112,17 +113,40 @@ public class BureauRegistry } /** - * Provides the Bureau registry with necessary runtime configuration. + * Provides the Bureau registry with necessary runtime configuration. Inserts the bureau + * client factory into the client manager and registers observers to track the progress + * of launched bureaus. */ public void init () { + _clmgr.addClientObserver(new ClientManager.ClientObserver() { + public void clientSessionDidStart (PresentsClient client) { + String id = BureauCredentials.extractBureauId(client.getUsername()); + if (id != null) { + sessionDidStart(client, id); + } + } + public void clientSessionDidEnd (PresentsClient client) { + String id = BureauCredentials.extractBureauId(client.getUsername()); + if (id != null) { + sessionDidEnd(client, id); + } + } + }); + + // add the client factory, but later, after all the other modules have been initialized + _omgr.postRunnable(new Runnable() { + public void run () { + addClientFactory(_clmgr); + } + }); } /** * Install the bureau client factory in the manager, delegating to the current factory * for non-bureau connections. */ - public void addClientFactory (ClientManager clmgr) + @Deprecated public void addClientFactory (ClientManager clmgr) { clmgr.setClientFactory( new BureauClientFactory(clmgr.getClientFactory())); @@ -293,6 +317,50 @@ public class BureauRegistry found.bureau.summarize(); } + /** + * Returns the active session for a bureau of the given id. + */ + public PresentsClient lookupClient (String bureauId) + { + Bureau bureau = _bureaus.get(bureauId); + if (bureau == null) { + return null; + } + return bureau.client; + } + + protected void sessionDidStart (PresentsClient client, String id) + { + Bureau bureau = _bureaus.get(id); + if (bureau == null) { + log.warning("Starting session for unknoqn bureau", "id", id, "client", client); + return; + } + if (bureau.client != null) { + log.warning( + "Multiple sessions for the same bureau", "id", id, "client", client, "bureau", + bureau); + } + bureau.client = client; + } + + protected void sessionDidEnd (PresentsClient client, String id) + { + Bureau bureau = _bureaus.get(id); + if (bureau == null) { + log.warning("Ending session for unknown bureau", "id", id, "client", client); + return; + } + if (bureau.client == null) { + log.warning( + "Multiple logouts from the same bureau", "id", id, "client", client, "bureau", + bureau); + } + bureau.client = null; + + clientDestroyed(bureau); + } + /** * Callback for when the bureau client acknowledges starting up. Starts all pending agents and * causes subsequent agent start requests to be sent directly to the bureau. @@ -445,6 +513,11 @@ public class BureauRegistry for (AgentObject agent : bureau.agentStates.keySet()) { _omgr.destroyObject(agent.getOid()); } + bureau.agentStates.clear(); + + if (_bureaus.remove(bureau.bureauId) == null) { + log.info("Bureau not found to remove", "bureau", bureau); + } } /** @@ -598,6 +671,9 @@ public class BureauRegistry // the registry ClientObject clientObj; + // The client session + PresentsClient client; + // The states of the various agents allocated to this bureau Map agentStates = Maps.newHashMap(); @@ -658,4 +734,5 @@ public class BureauRegistry @Inject protected RootDObjectManager _omgr; @Inject protected @MainInvoker Invoker _invoker; + @Inject protected ClientManager _clmgr; }