package org.radargun; import java.io.IOException; import java.net.InetAddress; import java.util.HashMap; import java.util.Map; import java.util.UUID; import org.radargun.config.Cluster; import org.radargun.config.Configuration; import org.radargun.config.Definition; import org.radargun.config.Evaluator; import org.radargun.config.PropertyHelper; import org.radargun.config.Scenario; import org.radargun.config.VmArgs; import org.radargun.reporting.Timeline; import org.radargun.utils.ArgsHolder; import org.radargun.utils.RestartHelper; import org.radargun.utils.SlaveConnectionInfo; import org.radargun.utils.Utils; /** * Slave being coordinated by a single {@link Master} object in order to run benchmarks. * * @author Mircea Markus <Mircea.Markus@jboss.com> */ public class Slave extends SlaveBase { private RemoteMasterConnection connection; public Slave(RemoteMasterConnection connection) { this.connection = connection; Runtime.getRuntime().addShutdownHook(new ShutDownHook("Slave process")); } private void run(int slaveIndex) throws Exception { log.debugf("Started with UUID %s", ArgsHolder.getUuid()); InetAddress address = connection.connectToMaster(slaveIndex); // the provided slaveIndex is just a "recommendation" state.setSlaveIndex(connection.receiveSlaveIndex()); log.info("Received slave index " + state.getSlaveIndex()); state.setMaxClusterSize(connection.receiveSlaveCount()); log.info("Received slave count " + state.getMaxClusterSize()); state.setLocalAddress(address); while (true) { Object object = connection.receiveObject(); log.trace("Received " + object); if (object == null) { log.info("Master shutdown!"); break; } else if (object instanceof RemoteSlaveConnection.Restart) { UUID nextUuid = UUID.randomUUID(); // At this point, slaveIndex == -1 so get index from state Configuration.Setup setup = configuration.getSetup(cluster.getGroup(state.getSlaveIndex()).name); VmArgs vmArgs = new VmArgs(); PropertyHelper.setPropertiesFromDefinitions(vmArgs, setup.getVmArgs(), getCurrentExtras(configuration, cluster)); HashMap<String, String> envs = new HashMap<>(); for (Map.Entry<String, Definition> entry : setup.getEnvironment().entrySet()) { envs.put(entry.getKey(), Evaluator.parseString(entry.getValue().toString())); } RestartHelper.spawnSlave(state.getSlaveIndex(), nextUuid, setup.plugin, vmArgs, envs); connection.sendObject(null, nextUuid); connection.release(); ShutDownHook.exit(0); } else if (object instanceof Scenario) { scenario = (Scenario) object; ScenarioRunner runner = new ScenarioRunner(); runner.start(); runner.join(); // we got ScenarioCleanup, now run the cleanup runCleanup(); } else if (object instanceof Configuration) { configuration = (Configuration) object; state.setConfigName(configuration.name); } else if (object instanceof Cluster) { cluster = (Cluster) object; } else if (object instanceof Timeline.Request) { connection.sendObject(state.getTimeline(), null); } else if (object instanceof SlaveConnectionInfo.Request) { connection.sendObject(Utils.getSlaveConnectionInfo(state.getSlaveIndex()), null); } else if (object instanceof RemoteSlaveConnection.SlaveAddresses) { state.setSlaveAddresses((RemoteSlaveConnection.SlaveAddresses) object); } } ShutDownHook.exit(0); } public static void main(String[] args) { ArgsHolder.init(args, ArgsHolder.ArgType.SLAVE); RestartHelper.init(); if (ArgsHolder.getMasterHost() == null) { ArgsHolder.printUsageAndExit(ArgsHolder.ArgType.SLAVE); } Slave slave = new Slave(new RemoteMasterConnection(ArgsHolder.getMasterHost(), ArgsHolder.getMasterPort())); try { slave.run(ArgsHolder.getSlaveIndex()); } catch (Exception e) { e.printStackTrace(); ShutDownHook.exit(127); } } @Override protected int getNextStageId() throws IOException { return connection.receiveNextStageId(); } @Override protected Map<String, Object> getNextMasterData() throws IOException { return (Map<String, Object>) connection.receiveObject(); } @Override protected void sendResponse(DistStageAck response) throws IOException { connection.sendObject(response, null); } @Override protected Map<String, String> getCurrentExtras(Configuration configuration, Cluster cluster) { Map<String, String> extras = new HashMap<String, String>(); extras.put(Properties.PROPERTY_CONFIG_NAME, configuration.name); extras.put(Properties.PROPERTY_PLUGIN_NAME, state.getPlugin()); extras.put(Properties.PROPERTY_CLUSTER_SIZE, String.valueOf(cluster.getSize())); extras.put(Properties.PROPERTY_CLUSTER_MAX_SIZE, String.valueOf(state.getMaxClusterSize())); extras.put(Properties.PROPERTY_SLAVE_INDEX, String.valueOf(state.getSlaveIndex())); Cluster.Group group = cluster.getGroup(state.getSlaveIndex()); extras.put(Properties.PROPERTY_GROUP_NAME, group.name); extras.put(Properties.PROPERTY_GROUP_SIZE, String.valueOf(group.size)); for (Cluster.Group g : cluster.getGroups()) { for(int i = 0; i != g.size; i++){ SlaveConnectionInfo ifaces = state.getSlaveAddresses(cluster, g.name, i); for (String s: ifaces.getInterfaceNames()) { extras.put(Properties.PROPERTY_GROUP_PREFIX + g.name + "." + i + "." + s, ifaces.getAddressesAsString(s, ",")); } } } for (Cluster.Group g : cluster.getGroups()) { extras.put(Properties.PROPERTY_GROUP_PREFIX + g.name + Properties.PROPERTY_SIZE_SUFFIX, String.valueOf(group.size)); } extras.put(Properties.PROPERTY_PROCESS_ID, String.valueOf(Utils.getProcessID())); return extras; } }