TaskMaster TODO list:
* = should be done
? = should it be done, or a question

TODO for TaskMaster 0.1.0:
* Add retry of deleted (dead or uncontactable machines) (done 1/18/2002)
* Add client attribute query mechanism (done 1/18/2002)

TODO for TaskMaster 0.2.0:
* Add port flexibility - allow other ports for clients besides 9000.
  - for example: zeph:9876,zeph:9999,zeph
    would allow for three different clients running on zeph.
* Add mechanism for resending tasks which may have 'hung' a client
  (may require some reworking of TaskMaster::send_task)
  - we could add an instance variable that gets mixed into a task object
    which tracks the number of times a task has been sent out.  A resend_limit
    could be set in TaskMaster so that the task is resent some number of 
    times not to exceed the resend_limit.  If resend_limit is 0 we never try
    to resend (that should be the default).  
? Should we introduce a Task module that should be mixed into all task objects
  the user creates?  It would check to see if 'run' has been overridden and
  it would add the @resend_limit handling to the user's task class.
  [partially done in 0.1.1]
? Investigate blocking tasks: tasks which muct be completed before continuing
  to more tasks.
  (perhaps we add a TaskMaster::send_task_blocking method)
* refactor TaskMaster::send_task so that it calls a next_available_client
  method which can be reused for other purposes.
? What about the concept of 'task groups': task objects which get executed in
  some specified order? (via blocking)
  ie:
     Task Group1:       task1
     Task Group2:       task2,task3,task4
     Task Group3:       task5,task6

  tasks in Group1 must complete before moving on to Group2 (but all of the 
  tasks in Group2 can be sent out at the same time).  And likewise, tasks in 
  Group3 depend on the resulsts from Group2 so the tasks in Group3 won't be 
  sent out until all tasks in Group2 have completed.  
  
  [should this be done at the TaskMaster level or should it be the 
  responsibility of the TaskMaster user?  For example: the TaskMaster user
  could send out task1 as bloked and wait for it to complete.  Then tasks
  2,3,and 4 can be sent out - the program can wait for them to complete
  before sending out tasks 5 and 6.  So perhaps this calls for an 'idiomatic'
  solution:

  group1 = [task1]
  group2 = [task2,task3,task4]
  group3 = [task5,task6]
  tm = TaskMaster.new(listOfClients)
  group1.each {|task|
    tm.send_task(task)
  }
  #wait for group1 task to complete
  tm.join_em
  group2.each {|task|
     tm.send_task(task)
  }
  tm.join_em
  group3.each {|task|
     tm.send_task(task)
  }
  tm.join_em

  ]
  
  ? Reintroduce the 'harvester' object?  - we now have the reporter that
  responds to 'report', but the naming may imply too much about behaviour.
  For example, you may not want to 'report' some results, but instead move
  some files around.  Whereas a 'reporter' is the same for the whole 
  TaskMaster instance, different havesters could accompany task objects.
  [Perhaps we don't need this - tasks can define a 'harvest' method and we
  already call that method after a task has finished]

  * Allow clients to 'put' via ftp.  (getfile and putfile)

  * Create method for sending files through dRuby 
    [stringify files and include them with filenames in an object that 
    gets sent around] - partially done in 0.1.1 (see FileBundle.rb)


OTHER IDEAS:

? How about a GUI frontend that allows the operator to add, remove
  slave machines on the fly.  Also it would allow jobs currently 
  running to be stopped (cancelled).  This would imply a threaded 
  queue.  The GUI would also graphically show the current status of
  all machines( 'red' = busy, 'yellow' = finished, 'green'=available,
  black = unavailable).

? How about a performance factor that would be calculated on slaves to 
  determine their relative performance.  The factor could be read in 
  ClientAttributes.

  

