/** Executes specified fence action on all fence agents concurrently */
  protected FenceOperationResult fenceConcurrently(FenceActionType fenceAction) {
    List<FenceOperationResult> results = new ArrayList<>(fenceAgents.size());
    FenceOperationResult taskResult;

    ExecutorCompletionService<FenceOperationResult> tasksExecutor =
        ThreadPoolUtil.createCompletionService();
    List<Future<FenceOperationResult>> futures =
        ThreadPoolUtil.submitTasks(tasksExecutor, createTasks(fenceAction));

    for (int i = 0; i < fenceAgents.size(); ++i) {
      try {
        taskResult = tasksExecutor.take().get();
      } catch (ExecutionException | InterruptedException e) {
        taskResult = new FenceOperationResult(Status.ERROR, PowerStatus.UNKNOWN, e.getMessage());
        log.error("Error getting task result: {}", e.getMessage());
        log.debug("Exception", e);
      }

      results.add(taskResult);
      if (tasksProcessor.isGoalReached(taskResult)) {
        // action goal is reach, cancel all remaining tasks
        for (Future<FenceOperationResult> future : futures) {
          future.cancel(true);
        }
        break;
      }
    }
    return tasksProcessor.createActionResult(results);
  }