code: private synchronized boolean canLaunchJobCleanupTask() {
      // check if the job is running
      if (status.getRunState() != JobStatus.RUNNING &&
          status.getRunState() != JobStatus.PREP) {
        return false;
      }
      // check if cleanup task has been launched already or if setup isn't
      // launched already. The later check is useful when number of maps is
      // zero.
      if (launchedCleanup || !isSetupFinished()) {
        return false;
      }
      // check if job has failed or killed
      if (jobKilled || jobFailed) {
        return true;
      }
  
      boolean mapsDone = ((finishedMapTasks + failedMapTIPs) == (numMapTasks));
      boolean reducesDone = ((finishedReduceTasks + failedReduceTIPs) == numReduceTasks);
      boolean mapOnlyJob = (numReduceTasks == 0);
  
      if (mapOnlyJob) {
        return mapsDone;
      }
      if (jobFinishWhenReducesDone) {
        return reducesDone;
      }
      return mapsDone && reducesDone;
    }
docs: Check whether cleanup task can be launched for the job.
  
  Cleanup task can be launched if it is not already launched
  or job is Killed
  or all maps and reduces are complete
  @return true/false