/** * Get job information * * @param id * @return * @throws NoSuchElementException if job with specified <code>id</code> does not exist */ public JobInfo getJobInfo(int id) throws NoSuchElementException { PrioritizedRequest request = _jobs.get(id); if (request == null) { throw new NoSuchElementException("Job not found : Job-" + id); } return request.toJobInfo(); }
/** * Cancel the request. Any IO in progress will be interrupted. * * @param id * @param explanation A reason to log * @throws NoSuchElementException */ public synchronized void cancel(int id, @Nullable String explanation) throws NoSuchElementException { PrioritizedRequest request = _jobs.get(id); if (request == null) { throw new NoSuchElementException("Job " + id + " not found"); } request.kill(explanation); if (_queue.remove(request)) { postprocessWithoutJobSlot(request); } }
/** * 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; } }
/** * Get mover id for given door request. If there is no mover associated with {@code * doorUniqueueRequest} a new mover will be created by using provided {@code moverSupplier}. * * <p>The returned mover id generated with following encoding: | 31- queue id -24|23- job id -0| * * @param moverSupplier {@link MoverSupplier} which can create a mover for given requests. * @param doorUniqueId unique request identifier generated by the door. * @param priority * @return mover id */ public int getOrCreateMover(MoverSupplier moverSupplier, String doorUniqueId, IoPriority priority) throws CacheException { checkState(!_isShutdown); try { /* Create the request if it doesn't already exists. */ PrioritizedRequest request = _moverByRequests.computeIfAbsent( doorUniqueId, key -> { try { return createRequest(moverSupplier, key, priority); } catch (CacheException e) { throw new RuntimeException(e); } }); /* If not already queued, submit it. */ if (request.queue()) { if (submit(request)) { /* There was a free slot in the queue so we submit directly to execution. */ sendToExecution(request); } else if (_semaphore.getMaxPermits() <= 0) { LOGGER.warn( "A task was added to queue '{}', however the queue is not " + "configured to execute any tasks.", _name); } } return request.getId(); } catch (RuntimeException e) { Throwables.propagateIfInstanceOf(e.getCause(), CacheException.class); throw e; } }
private void postprocessWithoutJobSlot(PrioritizedRequest request) { try (CDC ignore = request.getCdc().restore()) { request .getMover() .close( new CompletionHandler<Void, Void>() { @Override public void completed(Void result, Void attachment) { release(); } private void release() { request.done(); _jobs.remove(request.getId()); _moverByRequests.remove(request.getDoorUniqueId()); } @Override public void failed(Throwable exc, Void attachment) { release(); } }); } }
private void sendToExecution(final PrioritizedRequest request) { try (CDC ignore = request.getCdc().restore()) { request.transfer( new CompletionHandler<Void, Void>() { @Override public void completed(Void result, Void attachment) { postprocess(); } @Override public void failed(Throwable exc, Void attachment) { if (exc instanceof InterruptedException || exc instanceof InterruptedIOException) { request .getMover() .setTransferStatus(CacheException.DEFAULT_ERROR_CODE, "Transfer was killed"); } else if (exc instanceof DiskErrorCacheException) { FaultEvent faultEvent = new FaultEvent("transfer", FaultAction.DISABLED, exc.getMessage(), exc); _faultListeners.forEach(l -> l.faultOccurred(faultEvent)); } postprocess(); } private void postprocess() { try (CDC ignore = request.getCdc().restore()) { request .getMover() .close( new CompletionHandler<Void, Void>() { @Override public void completed(Void result, Void attachment) { release(); } @Override public void failed(Throwable exc, Void attachment) { if (exc instanceof DiskErrorCacheException) { FaultEvent faultEvent = new FaultEvent( "post-processing", FaultAction.DISABLED, exc.getMessage(), exc); _faultListeners.forEach(l -> l.faultOccurred(faultEvent)); } release(); } private void release() { request.done(); _jobs.remove(request.getId()); _moverByRequests.remove(request.getDoorUniqueId()); PrioritizedRequest nextRequest = nextOrRelease(); if (nextRequest != null) { sendToExecution(nextRequest); } } }); } } }); } }