/*
  * This is called when
  * 1) Current file deletion task ran and finished.
  * 2) This can be even directly called by predecessor task if one of the
  * dependent tasks of it has failed marking its success = false.
  */
 private synchronized void fileDeletionTaskFinished() {
   try {
     delService.stateStore.removeDeletionTask(taskId);
   } catch (IOException e) {
     LOG.error("Unable to remove deletion task " + taskId + " from state store", e);
   }
   Iterator<FileDeletionTask> successorTaskI = this.successorTaskSet.iterator();
   while (successorTaskI.hasNext()) {
     FileDeletionTask successorTask = successorTaskI.next();
     if (!success) {
       successorTask.setSuccess(success);
     }
     int count = successorTask.decrementAndGetPendingPredecessorTasks();
     if (count == 0) {
       if (successorTask.getSucess()) {
         successorTask.delService.scheduleFileDeletionTask(successorTask);
       } else {
         successorTask.fileDeletionTaskFinished();
       }
     }
   }
 }
  private void recordDeletionTaskInStateStore(FileDeletionTask task) {
    if (!stateStore.canRecover()) {
      // optimize the case where we aren't really recording
      return;
    }
    if (task.taskId != FileDeletionTask.INVALID_TASK_ID) {
      return; // task already recorded
    }

    task.taskId = generateTaskId();

    FileDeletionTask[] successors = task.getSuccessorTasks();

    // store successors first to ensure task IDs have been generated for them
    for (FileDeletionTask successor : successors) {
      recordDeletionTaskInStateStore(successor);
    }

    DeletionServiceDeleteTaskProto.Builder builder = DeletionServiceDeleteTaskProto.newBuilder();
    builder.setId(task.taskId);
    if (task.getUser() != null) {
      builder.setUser(task.getUser());
    }
    if (task.getSubDir() != null) {
      builder.setSubdir(task.getSubDir().toString());
    }
    builder.setDeletionTime(
        System.currentTimeMillis() + TimeUnit.MILLISECONDS.convert(debugDelay, TimeUnit.SECONDS));
    if (task.getBaseDirs() != null) {
      for (Path dir : task.getBaseDirs()) {
        builder.addBasedirs(dir.toString());
      }
    }
    for (FileDeletionTask successor : successors) {
      builder.addSuccessorIds(successor.taskId);
    }

    try {
      stateStore.storeDeletionTask(task.taskId, builder.build());
    } catch (IOException e) {
      LOG.error("Unable to store deletion task " + task.taskId + " for " + task.getSubDir(), e);
    }
  }
 /**
  * If there is a task dependency between say tasks 1,2,3 such that task2 and task3 can be
  * started only after task1 then we should define task2 and task3 as successor tasks for task1.
  * Note:- Task dependency should be defined prior to
  *
  * @param successorTask
  */
 public synchronized void addFileDeletionTaskDependency(FileDeletionTask successorTask) {
   if (successorTaskSet.add(successorTask)) {
     successorTask.incrementAndGetPendingPredecessorTasks();
   }
 }