Package org.jcsp.net.remote

# Class RemoteProcess

java.lang.Object
org.jcsp.net.remote.RemoteProcess

All Implemented Interfaces:
  `CSProcess`

public class RemoteProcess extends Object implements CSProcess

A proxy process that runs locally while another process executes on a different node. An instance is created with a `CSProcess` and an address of a remote node to execute the process on. This proxy is itself a `CSProcess` so can be used in a PAR construct. When `run` it will trigger the remote process. The local `run` will not return until the remote process has terminated.

A factory can be specified to control how the remote process initializes its `Node`. The factory used to initialize the local node should be passed to the remote node so that it will use the same CNS and configure other services in the same manner. For example, to initialize from the same XML file:

       NodeFactory nf = new XMLNodeFactory ("config.xml");
       try {
         Node.getInstance ().init (nf);
       } catch (NodeNotInitializedException e) {
         System.exit (1);
       }
       NodeAddressID slaveNode1 = new TCPIPAddressID ("123.45.6.78", 6000);
       NodeAddressID slaveNode2 = new TCPIPAddressID ("123.45.6.79", 6000);
       CSProcess proc1 = ...;
       CSProcess proc2 = ...;
       new Parallel (new CSProcess[] {
         new RemoteProcess (proc1, slaveNode1, nf),
         new RemoteProcess (proc2, slaveNode2, nf)
       }).run ();

If the local node has class files that won't be available at the remote node it can specify a network location for a classpath that the remote node should use to get classes from. Dynamic class loading is not currently implemented for remote spawning in this release.

       NodeAddressID slaveNode1 = new TCPIPAddressID ("123.45.6.78", 6000);
       NodeAddressID slaveNode2 = new TCPIPAddressID ("123.45.6.79", 6000);
       CSProcess proc1 = ...;
       CSProcess proc2 = ...;
       new Parallel (new CSProcess[] {
         new RemoteProcess (proc1, slaveNode1, "\\\\FileServer\\Packages"),
         new RemoteProcess (proc2, slaveNode2, "\\\\FileServer\\Packages")
       }).run ();

The remote process will be started in its own JVM and so this approach is not recommended for many small processes at the same node. If a number of remote processes are required it is suggested that a process responsible for creating the others be started remotely. For example:

       class WorkerGroup implements CSProcess, Serializable {

         private final int numWorkers;
         private final NetChannelLocation farmer, harvester;

         public WorkerGroup (int numWorkers, NetChannelLocation farmer,
                               NetChannelLocation harvester) {
           this.numWorkers = numWorkers;
         }

         public void run () {
           CSProcess workers[] = new CSProcess[numWorkers];
           for (int i = 0; i invalid input: '<' numWorkers; i++) {
             workers[i] = new Worker (farmer, harvester);
           }
           new Parallel (workers).run ();
         }
       }

       NodeAddressID slaveNode1 = new TCPIPAddressID ("123.45.6.78", 6000);
       NodeAddressID slaveNode2 = new TCPIPAddressID ("123.45.6.79", 6000);
       NetChannelInput workers2farmer    = NetChannelEnd.createNet2One ();
       NetChannelInput workers2harvester = NetChannelEnd.createNet2One ();
       One2OneChannel farmer2harvester   = Channel.one2one ();
       new Parallel (new CSProcess[] {
         new Farmer (farmer2harvester.out (), workers2farmer),
         new Harvester (farmer2harvester.in (), workers2harvester),
         new RemoteProcess (new WorkerGroup (10, workers2farmer.getChannelLocation (),
                                             workers2harvester.getChannelLocation ()),
                            slaveNode1),
         new RemoteProcess (new WorkerGroup (10, workers2farmer.getChannelLocation (),
                                             workers2harvester.getChannelLocation ()),
                            slaveNode2),
       }).run ();

Using a single `RemoteProcess` for each remote node is more efficient than using a `RemoteProcess` for each of the 10 worker processes at each node.

If a process needs an application ID it should call the static `getApplicationID`. If this is the only node running, it will allocate a new ID. If the process running was started remotely then the application ID of the parent node will be returned.

Author:
  Quickstone Technologies Limited

## Constructor Summary

Constructors
Constructor
Description
`RemoteProcess(CSProcess process, NodeAddressID remoteNode)`
Constructs a new proxy.
`RemoteProcess(CSProcess process, NodeAddressID remoteNode, String classPath)`
Constructs a new proxy.
`RemoteProcess(CSProcess process, NodeAddressID remoteNode, NodeFactory factory)`
Constructs a new proxy.
`RemoteProcess(CSProcess process, NodeAddressID remoteNode, NodeFactory factory, String classPath)`
Constructs a new proxy.

## Method Summary

Modifier and Type
Method
Description
`static ApplicationID`
`getApplicationID()`
Returns the application ID.
`boolean`
`lastRunStatus()`
Returns false iff the last run generated one or more exceptions.
`void`
`run()`
The main process body.

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

## Constructor Details

### RemoteProcess

public RemoteProcess(CSProcess process, NodeAddressID remoteNode)
Constructs a new proxy.

Parameters:
  `process` - the process to launch remotely.
  `remoteNode` - the node to launch the process on.

### RemoteProcess

public RemoteProcess(CSProcess process, NodeAddressID remoteNode, NodeFactory factory)
Constructs a new proxy.

Parameters:
  `process` - the process to launch remotely.
  `remoteNode` - the node to launch the process on.
  `nodeFactory` - the factory to use for initializing the remote node.

### RemoteProcess

public RemoteProcess(CSProcess process, NodeAddressID remoteNode, String classPath)
Constructs a new proxy.

Parameters:
  `process` - the process to launch remotely.
  `remoteNode` - the node to launch the process on.
  `classPath` - the classpath the remote JVM should use.

### RemoteProcess

public RemoteProcess(CSProcess process, NodeAddressID remoteNode, NodeFactory factory, String classPath)
Constructs a new proxy.

Parameters:
  `process` - the process to launch remotely.
  `remoteNode` - the node to launch the process on.
  `factory` - the factory to use for initializing the remote node.
  `classPath` - the classpath the remote JVM should use.

## Method Details

### getApplicationID

public static ApplicationID getApplicationID()
Returns the application ID. If the caller of this was started as a remote process then the parent's application ID will be returned. If this is the first node started then a new application ID is allocated.

Returns:
  the application ID.

### run

public void run()

The main process body. This will communicate with the remote node and send it the information needed to spawn the remote process. And output from the remote process will be put onto the system output streams. If the remote process throws an exception this will rethrow the same exception to the caller.

If there is a problem with the remote process, such as it throwing a checked exception or error, a `RemoteSpawnException` will be rethrown which contains the actual exception from the process.

Specified by:
  `run` in interface `CSProcess`
Throws:
  `RemoteSpawnException` - if there was a serious problem with the remote process.
  `RemoteProcessFailedException` - if the remote JVM terminated with a non-zero error code.

### lastRunStatus

public boolean lastRunStatus()
Returns false iff the last run generated one or more exceptions.