@Override
  protected void chore() {
    CompletableFuture<Boolean> f;
    synchronized (this) {
      if (!enabled.get()) {
        if (!forceRun) {
          LOG.trace("Cleaner chore {} disabled! Not cleaning.", getName());
          return;
        } else {
          LOG.info("Force executing cleaner chore {} when disabled", getName());
        }
      }
      if (future != null) {
        LOG.warn("A cleaner chore {}'s run is in progress, give up running", getName());
        return;
      }
      f = new CompletableFuture<>();
      future = f;
      notifyAll();
    }
    pool.latchCountUp();
    try {
      preRunCleaner();
      pool.execute(() -> traverseAndDelete(oldFileDir, true, f));
      if (f.get()) {
        LOG.trace("Cleaned all files under {}", oldFileDir);
      } else {
        LOG.trace("Files outstanding under {}", oldFileDir);
      }
    } catch (Exception e) {
      LOG.info("Failed to traverse and delete the dir: {}", oldFileDir, e);
    } finally {
      postRunCleaner();
      synchronized (this) {
        future = null;
        forceRun = false;
      }
      pool.latchCountDown();
      // After each cleaner chore, checks if received reconfigure notification while cleaning.
      // First in cleaner turns off notification, to avoid another cleaner updating pool again.
      // This cleaner is waiting for other cleaners finishing their jobs.
      // To avoid missing next chore, only wait 0.8 * period, then shutdown.
      pool.tryUpdatePoolSize((long) (0.8 * getTimeUnit().toMillis(getPeriod())));
    }
  }
A utility method to create new instances of LogCleanerDelegate based on the class name of the
LogCleanerDelegate.
@param className fully qualified class name of the LogCleanerDelegate
@param conf      used configuration
@return the new instance
hbase-server/src/main/java/org/apache/hadoop/hbase/master/cleaner/CleanerChore.java