code: private void revokeLock(String taskId, TaskLock lock)
    {
      giant.lock();
  
      try {
        if (!activeTasks.contains(taskId)) {
          throw new ISE("Cannot revoke lock for inactive task[%s]", taskId);
        }
  
        final Task task = taskStorage.getTask(taskId).orNull();
        if (task == null) {
          throw new ISE("Cannot revoke lock for unknown task[%s]", taskId);
        }
  
        log.info("Revoking task lock[%s] for task[%s]", lock, taskId);
  
        if (lock.isRevoked()) {
          log.warn("TaskLock[%s] is already revoked", lock);
        } else {
          final TaskLock revokedLock = lock.revokedCopy();
          taskStorage.replaceLock(taskId, lock, revokedLock);
  
          final List<TaskLockPosse> possesHolder = running.get(task.getDataSource()).get(lock.getInterval().getStart()).get(lock.getInterval());
          final TaskLockPosse foundPosse = possesHolder.stream()
                                                       .filter(posse -> posse.getTaskLock().equals(lock))
                                                       .findFirst()
                                                       .orElseThrow(
                                                           () -> new ISE("Failed to find lock posse for lock[%s]", lock)
                                                       );
          possesHolder.remove(foundPosse);
          possesHolder.add(foundPosse.withTaskLock(revokedLock));
          log.info("Revoked taskLock[%s]", lock);
        }
      }
      finally {
        giant.unlock();
      }
    }
docs: Mark the lock as revoked. Note that revoked locks are NOT removed. Instead, they are maintained in {@link #running}
  and {@link #taskStorage} as the normal locks do. This is to check locks are revoked when they are requested to be
  acquired and notify to the callers if revoked. Revoked locks are removed by calling
  {@link #unlock(Task, Interval)}.
  
  @param taskId an id of the task holding the lock
  @param lock   lock to be revoked