diff --git a/src/java/com/threerings/bureau/client/BureauDirector.java b/src/java/com/threerings/bureau/client/BureauDirector.java index 35a6aced5..452ec194c 100644 --- a/src/java/com/threerings/bureau/client/BureauDirector.java +++ b/src/java/com/threerings/bureau/client/BureauDirector.java @@ -49,8 +49,12 @@ public abstract class BureauDirector extends BasicDirector } }; - _subscriber = new SafeSubscriber(agentId, delegator); - _subscriber.subscribe(_ctx.getDObjectManager()); + Log.info("Subscribing to object " + agentId); + + SafeSubscriber subscriber = + new SafeSubscriber(agentId, delegator); + _subscribers.put(agentId, subscriber); + subscriber.subscribe(_ctx.getDObjectManager()); } /** @@ -62,6 +66,7 @@ public abstract class BureauDirector extends BasicDirector agent = _agents.remove(agentId); if (agent == null) { + Log.warning("Lost an agent, id " + agentId); } else { try { @@ -71,7 +76,13 @@ public abstract class BureauDirector extends BasicDirector Log.warning("Stopping an agent caused an exception"); Log.logStackTrace(t); } - _subscriber.unsubscribe(_ctx.getDObjectManager()); + SafeSubscriber subscriber = _subscribers.remove(agentId); + if (subscriber == null) { + Log.warning("Lost a subscriber for agent " + agent); + } + else { + subscriber.unsubscribe(_ctx.getDObjectManager()); + } _bureauService.agentDestroyed(_ctx.getClient(), agentId); } } @@ -82,6 +93,9 @@ public abstract class BureauDirector extends BasicDirector protected synchronized void objectAvailable (AgentObject agentObject) { int oid = agentObject.getOid(); + + Log.info("Object " + oid + " now available"); + Agent agent; try { agent = createAgent(agentObject); @@ -151,5 +165,6 @@ public abstract class BureauDirector extends BasicDirector protected BureauContext _ctx; protected BureauService _bureauService; protected IntMap _agents = IntMaps.newHashIntMap(); - protected SafeSubscriber _subscriber; + protected IntMap> _subscribers = + IntMaps.newHashIntMap(); } diff --git a/src/java/com/threerings/bureau/server/BureauRegistry.java b/src/java/com/threerings/bureau/server/BureauRegistry.java index 4fb4f3d15..c9ac5d035 100644 --- a/src/java/com/threerings/bureau/server/BureauRegistry.java +++ b/src/java/com/threerings/bureau/server/BureauRegistry.java @@ -123,12 +123,12 @@ public class BureauRegistry Bureau bureau = _bureaus.get(agent.bureauId); if (bureau != null && bureau.ready()) { + _omgr.registerObject(agent); + Log.info("Bureau ready, sending createAgent " + StringUtil.toString(agent)); BureauSender.createAgent(bureau.clientObj, agent.getOid()); - // !TODO: is this the right place to register the object? - _omgr.registerObject(agent); bureau.agentStates.put(agent, Bureau.STARTED); bureau.summarize(); @@ -193,7 +193,7 @@ public class BureauRegistry return; } - Log.warning("Destroying agent " + StringUtil.toString(agent)); + Log.info("Destroying agent " + StringUtil.toString(agent)); // transition the agent to a new state and perform the effect of the transition switch (found.state) { @@ -480,35 +480,48 @@ public class BureauRegistry // The states of the various agents allocated to this bureau Map agentStates = Maps.newHashMap(); + public String toString () + { + StringBuilder builder = new StringBuilder(); + builder.append("[Bureau id=").append(bureauId).append(", client="); + if (clientObj == null) { + builder.append("null"); + } + else { + builder.append(clientObj.getOid()); + } + builder.append(", process=").append(process); + builder.append(", totalAgents=").append(agentStates.size()); + agentSummary(builder.append(", ")).append("]"); + return builder.toString(); + } + boolean ready () { return clientObj != null; } - int countInState (int state) + StringBuilder agentSummary (StringBuilder str) { - Integer state1 = state; - if (!agentStates.containsValue(state1)) { - return 0; + int counts[] = {0, 0, 0, 0, 0}; + for (Map.Entry me : agentStates.entrySet()) { + counts[me.getValue()]++; } - int count = 0; - for (Map.Entry me : agentStates.entrySet()) { - if (me.getValue() == state1) { - ++count; - } - } - return count; + str.append(counts[PENDING]).append(" pending, "). + append(counts[STARTED]).append(" started, "). + append(counts[RUNNING]).append(" running, "). + append(counts[DESTROYED]).append(" destroyed, "). + append(counts[STILL_BORN]).append(" still born"); + return str; } void summarize () { - Log.info("Bureau " + bureauId + " [" + - countInState(PENDING) + " pending, " + - countInState(STARTED) + " started, " + - countInState(RUNNING) + " running, " + - countInState(DESTROYED) + " destroyed, " + - countInState(STILL_BORN) + " still born]"); + StringBuilder str = new StringBuilder(); + str.append("Bureau ").append(bureauId).append(" ["); + agentSummary(str).append("]"); + Log.info(str.toString()); } } diff --git a/tests/build.xml b/tests/build.xml index dd6e1f27e..c3c3d9ba9 100644 --- a/tests/build.xml +++ b/tests/build.xml @@ -187,6 +187,21 @@ + + + + + + + + + + + + + + = _maxAgents || + (size != 0 && _rng1.nextInt(100) >= _createChance)) { + AgentObject toRemove = _agents.remove(_rng1.nextInt(size)); + TestServer.log.info("Removing agent " + toRemove.getOid()); + _server.breg.destroyAgent(toRemove); + } + else { + AgentObject added = create(_rng1.nextInt(_numBureaus) + 1); + _agents.add(added); + TestServer.log.info("Added agent " + added.getOid()); + } + } + + /** + * Create and return a new agent for the given bureau. + */ + protected AgentObject create (int bureau) + { + AgentObject obj = new AgentObject(); + obj.bureauType = "test"; + obj.bureauId = "test-" + bureau; + _server.breg.startAgent(obj); + return obj; + } + + protected TestServer _server; + protected boolean _stop; + protected Random _rng1; + protected Random _rng2; + protected List _agents = Lists.newArrayList(); + + // maximum number of agents to keep around + protected int _maxAgents; + + // number of bureaus to select between + protected int _numBureaus; + + // number of operations to perform in one dobj queue task + protected int _maxOps; + + // chance of creating a new agent if limit has not been reached + protected int _createChance; + + // minimum delay between batches of requests + protected int _minDelay; + + // maximum delay between batches of requests + protected int _maxDelay; +} diff --git a/tests/src/java/com/threerings/bureau/server/TestServer.java b/tests/src/java/com/threerings/bureau/server/TestServer.java index 73aeeb703..7d1974d68 100644 --- a/tests/src/java/com/threerings/bureau/server/TestServer.java +++ b/tests/src/java/com/threerings/bureau/server/TestServer.java @@ -21,24 +21,35 @@ package com.threerings.bureau.server; -import com.threerings.bureau.Log; import com.threerings.bureau.data.AgentObject; import com.threerings.presents.server.PresentsServer; import com.samskivert.util.OneLineLogFormatter; import com.samskivert.util.StringUtil; - +import com.google.common.collect.Lists; import java.io.File; +import java.util.List; +import java.util.Random; +import java.util.logging.Level; +import java.util.logging.Logger; /** * Extends a presents server to include a bureau registry. */ public class TestServer extends PresentsServer { + /** We dispatch our log messages through this logger. */ + public static Logger log = Logger.getLogger(TestServer.class.getName()); + /** * The bureau registry for the server. Will be null until init is called. */ public static BureauRegistry breg; + public static void logStackTrace (Throwable t) + { + log.log(Level.WARNING, t.getMessage(), t); + } + /** * Creates a new server and runs it. */ @@ -50,21 +61,11 @@ public class TestServer extends PresentsServer final TestServer server = new TestServer(); try { server.init(); - - // request a new agent - // TODO: more tests here - create a thread that posts different kinds of requests - // and somehow monitors results from client - server.omgr.postRunnable(new Runnable() { - public void run () { - server.createTestAgent(); - } - }); - server.run(); } catch (Exception e) { - Log.warning("Unable to initialize server."); - Log.logStackTrace(e); + log.warning("Unable to initialize server."); + logStackTrace(e); } } @@ -93,15 +94,4 @@ public class TestServer extends PresentsServer } }); } - - /** - * Requests that the bureau client create an agent. - */ - protected void createTestAgent () - { - AgentObject obj = new AgentObject(); - obj.bureauType = "test"; - obj.bureauId = "test"; - breg.startAgent(obj); - } }