com.ibm.tspaces.services.utility
Class Worker

java.lang.Object
  |
  +--java.lang.Thread
        |
        +--com.ibm.tspaces.services.utility.Worker

public class Worker
extends java.lang.Thread

This class implements a TupleSpace worker that will take a Runnable object from a space and run it.

This class is inspired by the book MirrorWorld by David Gelernter. This implements his idea of clients that will grab tuples that contain eval() functions, run the procedure indicated by the eval() and then return the answer to the tuplespace.

In our case, the eval() function is represented by a Java Object that has a Eval interface. The Eval interface extends Runnable and Serializble. The Worker client will take tuples from the space that have the following format:

   Field 0   String  "Worker"   (WORKER_KEY)
   Field 1   String  type       Any type string that the user wants to assign
   Field 2   String  uniqueid   Any Id that is unique.  We use this to 
                                reflect back the result.
   Field 3   Eval    object     Any Object that contains a run() method that 
                                can be started.
 
When it get one of these Tuples, it will start a thread that will invoke the run() method for the Eval object. When the run method ends, it will regain control, use the getResult method to get the result and write the the following Tuple back into the space.
   Field 0   String  "WorkerResult"   (WORKER_RESULT)
   Field 1   String  type       Copied from input Tuple
   Field 2   String  uniqueid   Copied from input Tuple
   Field 3   Serializable result  Object that contains the result 
             
 
The program that is creating the work to be done will do the following: Assume that WorkerTest is a class whose run method does the work to be shared TupleSpace work = new TupleSpace(Worker._TSNAME,tsHost); WorkerTest wt = new WorkerTest(param1,param2); Tuple workTuple = new Tuple(Worker.WORKER_KEY,"WorkerTest","id1",wt); work.write(workTuple); Tuple template = new Tuple(Worker.WORKER_RESULT,"WorkerTest","id1",new Field(Serializable.class)); Tuple result = work.waitToTake(template); The constructor for WorkerTest would store any parameters needed by the run method as instance variables.

 When the Worker client takes one of the above Tuples from the space,
 it starts a new thread with the following code:
 
        Eval task = (Eval)workTuple.getField(3).getValue();
        String type = (String)workTuple.getField(1).getValue();
        String id = (String)workTuple.getField(2.getValue();
        Thread t = new Thread(task,type+"-"+id);
        t.start();
        t.join();
 
 

 When the run() method completes, we get back control at the join() and 
 we will write back a Tuple that contains the result

Author:
John Thomas
See Also:
Eval, Tuple, Field, TupleSpace

Field Summary
static java.lang.String WORKER_KEY
          Contents of 1st Field for work request
static java.lang.String WORKER_RESULT
          Contents of 1st Field for work results
static java.lang.String WORKER_TSHOST
          Default host for Worker Space
static java.lang.String WORKER_TSNAME
          Default name for the Worker Space
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
Worker(java.lang.String tsName, java.lang.String tsHost, int i)
          Create a Worker.
 
Method Summary
static void main(java.lang.String[] argv)
          The starting point of execution for the Worker thread We will parse the command line Usage: Worker [-D] [-h tsHost] [-n tsName] [number] number = the number of Worker threads to start.
 void run()
          The starting point of execution.
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, countStackFrames, currentThread, destroy, dumpStack, enumerate, getContextClassLoader, getName, getPriority, getThreadGroup, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setName, setPriority, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

WORKER_TSNAME

public static final java.lang.String WORKER_TSNAME
Default name for the Worker Space

WORKER_TSHOST

public static final java.lang.String WORKER_TSHOST
Default host for Worker Space

WORKER_KEY

public static final java.lang.String WORKER_KEY
Contents of 1st Field for work request

WORKER_RESULT

public static final java.lang.String WORKER_RESULT
Contents of 1st Field for work results
Constructor Detail

Worker

public Worker(java.lang.String tsName,
              java.lang.String tsHost,
              int i)
Create a Worker. We store the TupleSpace host name and space name for use by the run method.
Parameters:
tsName - the TupleSpace where the work Tuples are stored.
tsHost - the Host name whene the space is found
i - the index of the thread.
See Also:
TupleSpace
Method Detail

run

public void run()
The starting point of execution. This does the following:
  • Access the Worker TupleSpace
  • Do a waitToTake for a work Tuple (see prolog).
  • When it finds one, it extracts the Eval Object
  • Create a thread to run the run() method for the Eval instance
  • Lower the priority of the thread and then start it running
  • Issues a join().
  • When the thread ends we get back control
  • Call the Eval.getResult() method to get the result object
  • Write the WorkerResult Tuple back to the Worker space
  • Loop back and do another waitToTake
If an exception occurs, we will assume that the server space is broken (perhaps it was restarted, so we will start the entire process over at the beginning.
Overrides:
run in class java.lang.Thread

main

public static void main(java.lang.String[] argv)
The starting point of execution for the Worker thread We will parse the command line Usage: Worker [-D] [-h tsHost] [-n tsName] [number] number = the number of Worker threads to start. Default is 2 We then create the specified number of instances of Worker and then (since Worker implements Runnable) we start a thread for each instance.