package csci3366sample.masterworker.rmi; import java.net.InetAddress; import java.net.MalformedURLException; import java.net.UnknownHostException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import csci3366sample.masterworker.FakeTasks; /** * Generic example of master/worker program. * "Tasks" just consist of sleeping for a specified time; times to wait are * generatedly randomly from 1 to a specified maximum. * * Command-line arguments: hostname for server, * (optional) "--verbose" for verbose output * * Worker for client/server versions using RMI. * * RMI specifics in this example are loosely based on an example from * Sun's online tutorial. */ public class Worker implements WorkerInterface { /* variables */ private boolean verbose = false; private MasterInterface master; private String hostForMaster; private String myHostID; private int myID; private int totalTaskTime = 0; private int numTasks = 0; /* WorkerInterface methods */ public String getHostName() { return myHostID; } public int getID() { return myID; } /* other methods */ /** * Main method. */ public static void main(String[] args) { String usageMessage = "parameters: host [--verbose]"; final int REQUIRED_PARMS = 1; String host = null; boolean verbose = false; if (args.length < REQUIRED_PARMS) { System.err.println(usageMessage); System.exit(1); } host = args[0]; if (args.length > REQUIRED_PARMS) { if (args[REQUIRED_PARMS].equals("--verbose")) verbose = true; else { System.err.println(usageMessage); System.exit(1); } } /* do processing */ Worker w = null; try { w = new Worker(host, verbose); w.go(); } /* TODO: improve error handling? */ catch (Exception e) { System.err.println("error communicating with master:\n\t" + e); } /* * shut down: be sure there are no remaining references to * remote objects, since otherwise RMI keeps process(es) running */ if (w != null) { w.cleanupRMI(); } w = null; } /** Constructor. */ public Worker(String host, boolean _verbose) { verbose = _verbose; hostForMaster = host; } /** Perform processing. */ public void go() throws MalformedURLException, NotBoundException, RemoteException { /* get and save hostname */ try { myHostID = InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { myHostID = "unknown host"; } /* establish communication with master */ Registry registry = LocateRegistry.getRegistry(hostForMaster); master = (MasterInterface) registry.lookup(MasterInterface.BINDING_NAME); /* get worker ID from master */ myID = master.registerNewWorker(this); System.out.printf("worker %d starting\n", myID); /* process tasks until no more */ FakeTasks.Task t = null; while ( (t = master.getTask(this)) != null) { /* execute task and report result */ FakeTasks.TaskResult tr = t.execute(); if (verbose) { System.out.printf("worker %d received %s\n", myID, FakeTasks.toString(t, tr)); } master.reportResult(this, t, tr); /* update local totals */ ++numTasks; totalTaskTime += t.time; } /* report summary result */ master.reportSummaryResults(this, numTasks, totalTaskTime); System.out.printf("worker %d done\n", myID); } /** * Clean up all RMI-related resources. * (If references still exist to remote objects, RMI keeps process(es) * running.) */ public void cleanupRMI() { master = null; } }