How the best Job Runner is selected?

The best job runner is primarily selected based on the expected execution time on a particular job runner. Thus, the
job runnner on which a job will have the lowest execution time is selected.

Every time a job is executed the job runner that executed the job computes the execution time. This becomes
the instantaneous execution time of that job. This is added to a value that represents the cumulative execution time i.e. the sum
of execution times of  all jobs executed at the job runner. This sum is divided by the total number of jobs executed at
the job runner. In short, the average execution time of a job is computed. The average execution time multiplied by the
number of jobs actually executing on the job runner gives the instantaneous expected time that a new job might have to wait before
it begins execution. In reality a job will never need to wait because it will get scheduled immediately by the JVM by
allocating a new thread to it.  The figure is used to compare the best job runners. 

In some special cases the number of jobs executing on a job runner is a better statistic. The number of jobs is a useful statistic
when the job runner has just started up. Also, if a job runner has built up a wait time and is not executing jobs for a long time
the built up wait time is an incorrect indication. To avoid this, the wait time is decayed periodically, if the job runner is not
executing any jobs.

The class aashish.prt.JobRunnerInfo is used to maintain statistics of a job runner. The class aashish.prt.JobRunnerComparator
implements the comparison algorithm.

Example of a special case.
Runner1 has been running for quite some and has built up an imaginary expected wait time of 1000 but is currently not executing
any jobs. Runner2  has just started and is executing its first job that is taking a long time. Its wait time will be zero because it has
not completed execution of its first job and so has not built up any statistics.  In this case, the better host would be Runner2 because
it is not executing any jobs. The host selector will choose Runner2 and not Runner1 for a new job that comes in for execution. Logo