diff --git a/build.xml b/build.xml
index 7deb4209c..1e3d452ad 100644
--- a/build.xml
+++ b/build.xml
@@ -231,6 +231,7 @@
+
diff --git a/etc/libs-incl.xml b/etc/libs-incl.xml
index 6c8d3f034..7016147e5 100644
--- a/etc/libs-incl.xml
+++ b/etc/libs-incl.xml
@@ -15,6 +15,7 @@
+
diff --git a/src/java/com/threerings/bureau/server/BureauRegistry.java b/src/java/com/threerings/bureau/server/BureauRegistry.java
index 679c3e0a9..e3ed0c014 100644
--- a/src/java/com/threerings/bureau/server/BureauRegistry.java
+++ b/src/java/com/threerings/bureau/server/BureauRegistry.java
@@ -23,6 +23,7 @@ package com.threerings.bureau.server;
import java.util.Map;
import java.util.Set;
+import java.io.IOException;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -54,41 +55,38 @@ import static com.threerings.bureau.Log.log;
public class BureauRegistry
{
/**
- * Defines the commands that are responsible for invoking a bureau. Instances are associated to
- * bureau types by the server on startup. The instances are used whenever the registry needs to
- * launch a bureau for an agent with the assocated bureau type.
- * @see setCommandGenerator
+ * Defines how a bureau is launched. Instances are associated to bureau types by the server on
+ * startup. The instances are used whenever the registry needs to launch a bureau for an agent
+ * with the assocated bureau type.
+ */
+ public static interface Launcher
+ {
+ /**
+ * Kicks off a new bureau. This method will always be called on the unit invocation
+ * thread since it may do extensive I/O.
+ * @param bureauId the id of the bureau being launched
+ * @param token the secret string for the bureau to use in its credentials
+ */
+ void launchBureau (String bureauId, String token)
+ throws IOException;
+ }
+
+ /**
+ * Defines how to generate a command to launch a bureau in a local process.
+ * @see #setCommandGenerator
+ * @see Launcher
*/
public static interface CommandGenerator
{
/**
- * Launches a new bureau using the given server connect-back url and other information.
- * Called by the registry when it decides a new bureau is needed.
- * @param serverNameAndPort the name and port the bureau should use to connect back to the
- * server, e.g. server.com:47624
+ * Creates the command line to launch a new bureau using the given information.
+ * Called by the registry when a new bureau is needed whose type was registered
+ * with setCommandGenerator.
* @param bureauId the id of the bureau being launched
* @param token the token string to use for the credentials when logging in
- * @return the builder, ready to launch
+ * @return command line arguments, including executable name
*/
- String[] createCommand (
- String serverNameAndPort,
- String bureauId,
- String token);
- }
-
- /**
- * Thrown when a bureau could not be authenticated.
- */
- public static class AuthenticationException extends Exception
- {
- /**
- * Creates a new authentication exception with a message explaining why the client could
- * not be authenticated as a bureau.
- */
- public AuthenticationException (String message)
- {
- super(message);
- }
+ String[] createCommand (String bureauId, String token);
}
/**
@@ -115,9 +113,8 @@ public class BureauRegistry
/**
* Provides the Bureau registry with necessary runtime configuration.
*/
- public void init (String serverNameAndPort)
+ public void init ()
{
- _serverNameAndPort = serverNameAndPort;
}
/**
@@ -150,15 +147,43 @@ public class BureauRegistry
* @param bureauType the type of bureau that will be launched
* @param cmdGenerator the generator to be used for bureaus of bureauType
*/
- public void setCommandGenerator (String bureauType, CommandGenerator cmdGenerator)
+ public void setCommandGenerator (
+ String bureauType,
+ final CommandGenerator cmdGenerator)
{
- if (_generators.get(bureauType) != null) {
- log.warning("Generator for type already exists [type=" +
+ setLauncher(bureauType, new Launcher () {
+ public void launchBureau (String bureauId, String token)
+ throws IOException {
+ ProcessBuilder builder = new ProcessBuilder(
+ cmdGenerator.createCommand(bureauId, token));
+ builder.redirectErrorStream(true);
+ Process process = builder.start();
+ // log the output of the process and prefix with bureau id
+ ProcessLogger.copyMergedOutput(log, bureauId, process);
+ }
+
+ public String toString () {
+ return "DefaultLauncher for " + cmdGenerator;
+ }
+ });
+ }
+
+ /**
+ * Registers a launcher for a given type. When an agent is started and no bureaus are
+ * running, the bureauType is used to determine the Launcher
+ * instance to call.
+ * @param bureauType the type of bureau that will be launched
+ * @param launcher the launcher to be used for bureaus of bureauType
+ */
+ public void setLauncher (String bureauType, Launcher launcher)
+ {
+ if (_launchers.get(bureauType) != null) {
+ log.warning("Launcher for type already exists [type=" +
bureauType + "]");
return;
}
- _generators.put(bureauType, cmdGenerator);
+ _launchers.put(bureauType, launcher);
}
/**
@@ -184,29 +209,24 @@ public class BureauRegistry
if (bureau == null) {
- CommandGenerator generator = _generators.get(agent.bureauType);
- if (generator == null) {
- log.warning("CommandGenerator not found for agent's " +
+ Launcher launcher = _launchers.get(agent.bureauType);
+ if (launcher == null) {
+ log.warning("Launcher not found for agent's " +
"bureau type " + StringUtil.toString(agent));
return;
}
log.info("Creating new bureau " +
StringUtil.toString(agent.bureauId) + " " +
- StringUtil.toString(generator));
+ StringUtil.toString(launcher));
bureau = new Bureau();
bureau.bureauId = agent.bureauId;
bureau.token = generateToken(bureau.bureauId);
- // schedule the bureau to be kicked off
- bureau.builder = new ProcessBuilder(
- generator.createCommand(
- _serverNameAndPort, agent.bureauId, bureau.token));
+ bureau.launcher = launcher;
- bureau.builder.redirectErrorStream(true);
-
- _invoker.postUnit(new Launcher(bureau));
+ _invoker.postUnit(new LauncherUnit(bureau));
_bureaus.put(agent.bureauId, bureau);
}
@@ -473,32 +493,30 @@ public class BureauRegistry
/**
* Invoker unit to launch a bureau's process, then assign the result on the main thread.
*/
- protected static class Launcher extends Invoker.Unit
+ protected static class LauncherUnit extends Invoker.Unit
{
- Launcher (Bureau bureau)
+ LauncherUnit (Bureau bureau)
{
- super("Launcher for " + bureau +
- StringUtil.toString(bureau.builder.command()));
+ super("LauncherUnit for " + bureau + ": " +
+ StringUtil.toString(bureau.launcher));
_bureau = bureau;
}
public boolean invoke ()
{
try {
- _result = _bureau.builder.start();
- // log the output of the process and prefix with bureau id
- ProcessLogger.copyMergedOutput(log, _bureau.bureauId, _result);
+ _bureau.launch();
} catch (Exception e) {
- log.warning("Could not launch process", "bureau", _bureau, e);
+ log.warning("Could not launch bureau", e);
}
return true;
}
public void handleResult ()
{
- _bureau.process = _result;
- _bureau.builder = null;
+ _bureau.launched = true;
+ _bureau.launcher = null;
log.info("Bureau launched", "bureau", _bureau);
}
@@ -552,11 +570,11 @@ public class BureauRegistry
// }
- // non-null once the bureau is kicked off
- Process process;
-
// non-null once the bureau is scheduled but not yet kicked off
- ProcessBuilder builder;
+ Launcher launcher;
+
+ // non-null once the bureau is kicked off
+ boolean launched;
// The token given to this bureau for authentication
String token;
@@ -582,7 +600,8 @@ public class BureauRegistry
else {
builder.append(clientObj.getOid());
}
- builder.append(", process=").append(process);
+ builder.append(", launcher=").append(launcher);
+ builder.append(", launched=").append(launched);
builder.append(", totalAgents=").append(agentStates.size());
agentSummary(builder.append(", ")).append("]");
return builder.toString();
@@ -615,10 +634,15 @@ public class BureauRegistry
agentSummary(str).append("]");
log.info(str.toString());
}
+
+ void launch ()
+ throws IOException
+ {
+ launcher.launchBureau(bureauId, token);
+ }
}
- protected String _serverNameAndPort;
- protected Map _generators = Maps.newHashMap();
+ protected Map _launchers = Maps.newHashMap();
protected Map _bureaus = Maps.newHashMap();
@Inject protected RootDObjectManager _omgr;
diff --git a/tests/build.xml b/tests/build.xml
index dee197c2d..f08f82217 100644
--- a/tests/build.xml
+++ b/tests/build.xml
@@ -1,6 +1,9 @@
+
+
+
@@ -8,10 +11,14 @@
+
+
+
+
@@ -99,36 +106,63 @@
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -147,29 +181,48 @@
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
+ unless="no_build_thane_client" depends="aslib,bureau-check-thane-client"
+ description="Compiles the thane client for testing the bureau library">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
-
+
+
diff --git a/tests/etc/thane-config.xml.in b/tests/etc/thane-config.xml.in
new file mode 100644
index 000000000..c4ed9cfbc
--- /dev/null
+++ b/tests/etc/thane-config.xml.in
@@ -0,0 +1,366 @@
+
+
+
+
+
+ false
+
+
+
+ false
+
+ true
+
+
+
+ false
+
+
+
+
+
+
+ false
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+ @flex_sdk_dir@/frameworks/localFonts.ser
+
+
+ flash.fonts.JREFontManager
+ flash.fonts.AFEFontManager
+ flash.fonts.BatikFontManager
+
+
+ 20
+
+ 1000
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+ en_US
+
+
+
+
+
+
+
+
+ http://www.adobe.com/2006/mxml
+ @flex_sdk_dir@/frameworks/mxml-manifest.xml
+
+
+
+ true
+
+
+
+ true
+
+ true
+
+ true
+
+ true
+
+
+
+ true
+
+
+
+ true
+
+ true
+
+ false
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ false
+
+ false
+
+ true
+
+ true
+
+ false
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ false
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ true
+
+ false
+
+ false
+
+ true
+
+ false
+
+ false
+
+ true
+
+ true
+
+ false
+
+
+
+
+ 0x869CA7
+
+ 30
+
+
+ 1000
+ 15
+
+
+
+ 500
+ 375
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Three Rings Design, Inc.
+
+
+
+ http://www.whirled.com
+
+ EN
+
+
+
+
+
+ Three Rings Design, Inc.
+
+ Whirled
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+ true
+
+
+
+
+
+
+
diff --git a/tests/src/as/Lib.as b/tests/src/as/Lib.as
deleted file mode 100644
index 99ec14ac0..000000000
--- a/tests/src/as/Lib.as
+++ /dev/null
@@ -1 +0,0 @@
-package {}
diff --git a/tests/src/as/com/threerings/bureau/client/TestClient.as b/tests/src/as/com/threerings/bureau/client/TestClient.as
index 811950266..7e5ef9030 100644
--- a/tests/src/as/com/threerings/bureau/client/TestClient.as
+++ b/tests/src/as/com/threerings/bureau/client/TestClient.as
@@ -1,7 +1,40 @@
package com.threerings.bureau.client {
+import com.threerings.bureau.data.BureauMarshaller;
+
public class TestClient extends BureauClient
{
+ BureauMarshaller;
+
+ /**
+ * The main entry point for the bureau test client to be run in thane. Arguments:
+ * 0: the token to use to log back into the server
+ * 1: the bureau id of this instance
+ * 2: the name of the server to log into
+ * 3: the port to connect to on the server
+ */
+ public static function main (argv :Array) :void
+ {
+ if (argv.length != 4) {
+ trace("Expected 4 arguments: (token) (bureauId) (server) (port)");
+ }
+
+ var token :String = argv[0];
+ var bureauId :String = argv[1];
+ var server :String = argv[2];
+ var port :int = parseInt(argv[3]);
+
+ trace("Token: " + token);
+ trace("BureauId: " + bureauId);
+ trace("Server: " + server);
+ trace("Port: " + port + " (parsed from " + argv[3] + ")");
+
+ // create the client and log on
+ var client :TestClient = new TestClient(token, bureauId);
+ client.setServer(server, [port]);
+ client.logon();
+ }
+
public function TestClient (token :String, bureauId :String)
{
super(token, bureauId);
diff --git a/tests/src/as/com/threerings/bureau/client/TestClientMain.as b/tests/src/as/com/threerings/bureau/client/TestClientMain.as
deleted file mode 100644
index 17c147ece..000000000
--- a/tests/src/as/com/threerings/bureau/client/TestClientMain.as
+++ /dev/null
@@ -1,33 +0,0 @@
-
-/**
- * The main entry point for the bureau test client to be run in thane. Arguments:
- * 0: the token to use to log back into the server
- * 1: the bureau id of this instance
- * 2: the name of the server to log into
- * 3: the port to connect to on the server
- */
-
-import avmplus.System;
-import com.threerings.bureau.client.TestClient;
-
-if (System.argv.length != 4) {
- trace("Expected 4 arguments: (token) (bureauId) (server) (port)");
-}
-
-var token :String = System.argv[0];
-var bureauId :String = System.argv[1];
-var server :String = System.argv[2];
-var port :int = parseInt(System.argv[3]);
-
-trace("Token: " + token);
-trace("BureauId: " + bureauId);
-trace("Server: " + server);
-trace("Port: " + port + " (parsed from " + System.argv[3] + ")");
-
-// create the client and log on
-var client :TestClient = new TestClient(token, bureauId);
-client.setServer(server, [port]);
-client.logon();
-
-// run it
-//client.run();
diff --git a/tests/src/java/com/threerings/bureau/server/TestServer.java b/tests/src/java/com/threerings/bureau/server/TestServer.java
index f3a5584d6..c0c61704d 100644
--- a/tests/src/java/com/threerings/bureau/server/TestServer.java
+++ b/tests/src/java/com/threerings/bureau/server/TestServer.java
@@ -56,12 +56,11 @@ public class TestServer extends PresentsServer
public static BureauRegistry.CommandGenerator antCommandGenerator (final String target)
{
return new BureauRegistry.CommandGenerator() {
- public String[] createCommand (String serverNameAndPort, String bureauId, String token) {
- int colon = serverNameAndPort.indexOf(':');
+ public String[] createCommand (String bureauId, String token) {
return new String[] {
"ant",
- "-DserverName=" + serverNameAndPort.substring(0, colon),
- "-DserverPort=" + serverNameAndPort.substring(colon + 1),
+ "-DserverName=localhost",
+ "-DserverPort=47624",
"-DbureauId=" + bureauId,
"-Dtoken=" + token,
target };
@@ -74,7 +73,7 @@ public class TestServer extends PresentsServer
throws Exception
{
super.init(injector);
- _bureauReg.init("localhost:47624");
+ _bureauReg.init();
}
public void setClientTarget (String target)
diff --git a/tests/src/thane/BureauTestClient.as b/tests/src/thane/BureauTestClient.as
new file mode 100644
index 000000000..bfb18964d
--- /dev/null
+++ b/tests/src/thane/BureauTestClient.as
@@ -0,0 +1,11 @@
+package {
+
+import avmplus.System;
+import com.threerings.bureau.client.TestClient;
+
+
+public class BureauTestClient
+{
+ TestClient.main(System.argv);
+}
+}