public class FibTaskSpawn
extends CXTask {
// required constructor!
public FibTaskSpawn(TaskHeader taskHeader)
{
super(taskHeader);
}
// custom constructor(s)
public FibTaskSpawn(int
num)
{
//construct your task info
//in some cases this can be more complicated
//but it always follows the pattern bellow:
myTaskInfo=new TaskInfo();
myTaskInfo.isLocal=false; //even though you can make it local
myTaskInfo.taskType=CXConst.readyTask; //meaning ready to go, all input
arguments are present
inputArguments=new Integer[1];
inputArguments[0]=new Integer(num);
missingInputArguments=0;
outputDestination=new DestinationRecord[1]; //there is only one return
argument
}
// that's the only
method you must override
public
void executeTask(TaskContainer ts)
{
// that's the only method application programmer needs to overwrite
// first, get the (sole) input argument, which in out case is the number
// of the fibonucci function that we wish to evaluate, i.e. fib(num)
Integer fibNumber=(Integer) inputArguments[0];
int fnum=fibNumber.intValue();
System.out.println("FibTaskSpawn:"+fnum);
if (fnum<2)
{
// if the fibonucci number is less than 2,
// then I can do the calculations without spawning new tasks ...
TaskInfo taskInfo;
Sequence computedBy=new Sequence(myTaskInfo.taskId);
long jobId;
long argPos;
Integer[] result=new Integer[1];
if (outputDestination[0]!=null)
// this means that the results are intermediate, and must be returned to
another task - not the consumer
{
taskInfo=new TaskInfo(outputDestination[0].destinationTask);
argPos=outputDestination[0].inArgPos;
jobId=taskInfo.jobId;
}
else
{
// results are final - should be forwarder to consumer
taskInfo=null;
jobId=myTaskInfo.jobId;
argPos=0;
}
// now populate the result object that will be returned to your Task Container
result[0]=new Integer(fnum); //or whatever the result might be
Result res=new Result(taskInfo,computedBy,argPos,result);
res.jobId=jobId;
// send the newly created results to your task container
ts.storeResults(res);
}
else
{
// Instead of evaluating the fib(num) functions, you create three new tasks:
// Task t1, that corresponds to fib(num-1)
// Task t2, that corresponds to fib(num-2)
// Task ct, that will combine that results of the above tasks, i.e. will
execute the fib(num-1)+fib(num-2) opertation
Task t1=new FibTaskSpawn(fnum-1);
Task t2=new FibTaskSpawn(fnum-2);
Task ct=new FibTaskCombine();
// Configure new tasks
TaskInfo nti=new TaskInfo(myTaskInfo);
nti.taskId.jobId=myTaskInfo.jobId;
Sequence oldSeq=new Sequence(nti.taskId);
// start with the "combine" task ...
nti.isLocal=true; // should be executed within my Task Container ?
nti.taskType=CXConst.waitingTask; // should wait for some input arguments,
or it is ready to go?
nti.taskId=getNextSeqNum(oldSeq,1);
ct.setTaskInfo(nti);
if (outputDestination[0]!=null)
{
ct.setOutputDestination(0,outputDestination[0].destinationTask,outputDestination[0].inArgPos);
}
else
{
ct.setOutputDestination(0,null,0);
}
// now, fill in the arguments for fib(num-1) task ...
nti.taskId=getNextSeqNum(oldSeq,2);
nti.isLocal=false; //can be executed outside the current TS
nti.taskType=CXConst.readyTask; //ready to go!
t1.setTaskInfo(nti);
t1.setOutputDestination(0,ct.getTaskInfo(),0); // that will be the first
input argument of ct task
// fill in the arguments for fib(num-2) task ...
nti.taskId=getNextSeqNum(oldSeq,3);
nti.isLocal=false; //can be executed outside the current TS
nti.taskType=CXConst.readyTask; //ready to go!
t2.setTaskInfo(nti);
t2.setOutputDestination(0,ct.getTaskInfo(),1); // that will be the second
input argument of ct task
// send the newly created tasks to your task container
ts.storeTask(ct);
ts.storeTask(t1);
ts.storeTask(t2);
}
}
}
Make sure that you always: