private void killUnfinishedAttempt(TaskAttempt attempt, String logMsg) {
   if (commitAttempt != null && commitAttempt.equals(attempt)) {
     LOG.info("Removing commit attempt: " + commitAttempt);
     commitAttempt = null;
   }
   if (attempt != null && !attempt.isFinished()) {
     eventHandler.handle(new TaskAttemptEventKillRequest(attempt.getID(), logMsg));
   }
 }
  @Override
  public boolean canCommit(TezTaskAttemptID taskAttemptID) {
    writeLock.lock();
    try {
      if (getState() != TaskState.RUNNING) {
        LOG.info("Task not running. Issuing kill to bad commit attempt " + taskAttemptID);
        eventHandler.handle(
            new TaskAttemptEventKillRequest(taskAttemptID, "Task not running. Bad attempt."));
        return false;
      }
      if (commitAttempt == null) {
        TaskAttempt ta = getAttempt(taskAttemptID);
        if (ta == null) {
          throw new TezUncheckedException("Unknown task for commit: " + taskAttemptID);
        }
        // Its ok to get a non-locked state snapshot since we handle changes of
        // state in the task attempt. Dont want to deadlock here.
        TaskAttemptState taState = ta.getStateNoLock();
        if (taState == TaskAttemptState.RUNNING) {
          commitAttempt = taskAttemptID;
          LOG.info(taskAttemptID + " given a go for committing the task output.");
          return true;
        } else {
          LOG.info(
              taskAttemptID
                  + " with state: "
                  + taState
                  + " given a no-go for commit because its not running.");
          return false;
        }
      } else {
        if (commitAttempt.equals(taskAttemptID)) {
          LOG.info(taskAttemptID + " given a go for committing the task output.");
          return true;
        }
        // Don't think this can be a pluggable decision, so simply raise an
        // event for the TaskAttempt to delete its output.
        // Wait for commit attempt to succeed. Dont kill this. If commit
        // attempt fails then choose a different committer. When commit attempt
        // succeeds then this and others will be killed
        LOG.info(commitAttempt + " is current committer. Commit waiting for:  " + taskAttemptID);
        return false;
      }

    } finally {
      writeLock.unlock();
    }
  }