/**
  * Set maximal number of concurrently running jobs by this scheduler. All pending jobs will be
  * executed.
  *
  * @param maxJobs
  */
 public void setMaxActiveJobs(int maxJobs) {
   _semaphore.setMaxPermits(maxJobs);
   PrioritizedRequest request;
   while (_semaphore.tryAcquire() && (request = nextOrRelease()) != null) {
     sendToExecution(request);
   }
 }
  /** Shutdown the scheduler. All subsequent execution request will be rejected. */
  public void shutdown() throws InterruptedException {
    checkState(!_isShutdown);
    _isShutdown = true;

    /* Drain jobs from the queue so they will never be started. Has to be done
     * before killing jobs as otherwise the queued jobs will immediatley fill
     * the freed job slot.
     */
    Collection<PrioritizedRequest> toBeCancelled = new ArrayList<>();
    _queue.drainTo(toBeCancelled);

    /* Kill both the jobs that were queued and which are running. */
    _jobs.values().forEach(j -> j.kill("shutdown"));

    /* Jobs that were queued were never submitted for execution and thus we
     * manually trigger postprocessing.
     */
    toBeCancelled.forEach(this::postprocessWithoutJobSlot);

    LOGGER.info("Waiting for movers on queue '{}' to finish", _name);
    if (!_semaphore.tryAcquire(_semaphore.getMaxPermits(), 2, TimeUnit.SECONDS)) {
      // This is often due to a mover not reacting to interrupt or the transfer
      // doing a lengthy checksum calculation during post processing.
      String versions =
          _jobs
              .values()
              .stream()
              .map(PrioritizedRequest::getMover)
              .map(Mover::getProtocolInfo)
              .map(ProtocolInfo::getVersionString)
              .collect(joining(","));
      LOGGER.warn("Failed to terminate some movers prior to shutdown: {}", versions);
    }
  }
  /**
   * Add a request to the scheduler.
   *
   * <p>Returns true if the caller acquired a job slot and must send the job to execution.
   *
   * @param request
   * @return
   */
  private synchronized boolean submit(PrioritizedRequest request) {
    if (_jobs.put(request.getId(), request) != null) {
      throw new RuntimeException(
          "Duplicate mover id detected. Please report to [email protected].");
    }

    if (_semaphore.tryAcquire()) {
      return true;
    } else {
      _queue.add(request);
      return false;
    }
  }