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
This commit is contained in:
Jamie Doornbos
2008-07-18 00:06:06 +00:00
parent 8a72343130
commit 805372caf3
2 changed files with 98 additions and 3 deletions
@@ -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);
}
/**
@@ -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<AgentObject, Integer> agentStates = Maps.newHashMap();
@@ -658,4 +734,5 @@ public class BureauRegistry
@Inject protected RootDObjectManager _omgr;
@Inject protected @MainInvoker Invoker _invoker;
@Inject protected ClientManager _clmgr;
}