/** * 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; } }