@Override
 public void stateChanged(StateChangeEvent event) {
   if (event.getNewState() == ReplicaState.REMOVED) {
     PnfsId pnfsId = event.getPnfsId();
     stageRequests.cancel(pnfsId);
     flushRequests.cancel(pnfsId);
   }
 }
 @Override
 public void beforeStop() {
   /* Marks the containers as being shut down and cancels all requests, but
    * doesn't wait for termination.
    */
   flushRequests.shutdown();
   stageRequests.shutdown();
   removeRequests.shutdown();
 }
 /**
  * Stages a file from nearline storage.
  *
  * <p>TODO: Should eventually accept multiple files at once, but the rest of the pool doesn't
  * support that yet.
  *
  * @param file attributes of file to stage
  * @param callback callback notified when file is staged
  */
 public void stage(
     String hsmInstance, FileAttributes file, CompletionHandler<Void, PnfsId> callback) {
   try {
     NearlineStorage nearlineStorage = hsmSet.getNearlineStorageByName(hsmInstance);
     checkArgument(nearlineStorage != null, "No such nearline storage: " + hsmInstance);
     stageRequests.addAll(nearlineStorage, Collections.singleton(file), callback);
   } catch (RuntimeException e) {
     callback.failed(e, file.getPnfsId());
   }
 }
  @PreDestroy
  public void shutdown() throws InterruptedException {
    flushRequests.shutdown();
    stageRequests.shutdown();
    removeRequests.shutdown();

    if (timeoutFuture != null) {
      timeoutFuture.cancel(false);
    }
    repository.removeListener(this);

    /* Waits for all requests to have finished. This is blocking to avoid that the
     * repository gets closed nearline storage requests have had a chance to finish.
     */
    long deadline = System.currentTimeMillis() + 3000;
    if (flushRequests.awaitTermination(
        deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS)) {
      if (stageRequests.awaitTermination(
          deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS)) {
        removeRequests.awaitTermination(
            deadline - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
      }
    }
  }
 public int getFetchQueueSize() {
   return stageRequests.getCount(AbstractRequest.State.QUEUED);
 }
 public int getActiveFetchJobs() {
   return stageRequests.getCount(AbstractRequest.State.ACTIVE)
       + stageRequests.getCount(AbstractRequest.State.CANCELED);
 }