public void watch() {
    while (!shutdown.get()) {
      WatchKey watchKey;
      try {
        watchKey = watchService.take();
      } catch (InterruptedException e) {
        if (shutdown.get()) {
          LOG.info("Shutting down watcher");
          break;
        } else {
          LOG.error("Watcher interrupted before being shutdown");
          throw new RuntimeException("Watcher interrupted before being shutdown", e);
        }
      }
      Path watchedPath = (Path) watchKey.watchable();
      WatchedPathInfo parentWatchedPathInfo = watchedPaths.get(watchedPath);
      boolean cancelledWatch = false;
      for (WatchEvent<?> rawEvent : watchKey.pollEvents()) {
        if (rawEvent.kind().equals(OVERFLOW)) {
          // Ignoring and continuing to watch for additional elements in the dir.
          continue;
        }

        WatchEvent<Path> event = (WatchEvent<Path>) rawEvent;
        WatchedPathInfo watchedPathInfo;
        Path resolvedPath;

        switch (parentWatchedPathInfo.type) {
          case BASE:
            // Add the output dir to the watch set, scan it, and cancel current watch.
            if (event.context().getFileName().toString().equals(OUTPUT)) {
              resolvedPath = watchedPath.resolve(event.context());
              watchedPathInfo = new WatchedPathInfo(parentWatchedPathInfo, Type.OUTPUT, null);
              registerDir(resolvedPath, watchedPathInfo);
              // Scan the "output" directory for existing files, and add watches
              try (DirectoryStream<Path> dirStream = Files.newDirectoryStream(resolvedPath)) {
                for (Path path : dirStream) {
                  // This would be an attempt directory. Add a watch, and track it.
                  if (path.toFile().isDirectory()) {
                    watchedPathInfo = new WatchedPathInfo(parentWatchedPathInfo, Type.FINAL, path.getFileName().toString());
                    registerDir(path, watchedPathInfo);
                    scanForFinalFiles(watchedPathInfo, path);
                  } else {
                    LOG.warn("Ignoring unexpected file: " + path);
                  }
                }
              } catch (IOException e) {
                LOG.warn("Unable to list files under: " + resolvedPath);
              }
              // Cancel the watchKey since the output dir has been found.
              cancelledWatch = true;
              watchKey.cancel();
            } else {
              LOG.warn("DEBUG: Found unexpected directory while looking for OUTPUT: " + event.context() + " under " + watchedPath);
            }
            break;
          case OUTPUT:
            // Add the attemptDir to the watch set, scan it and add to the list of found files
            resolvedPath = watchedPath.resolve(event.context());
            // New attempt path crated. Add a watch on it, and scan it for existing files.
            watchedPathInfo = new WatchedPathInfo(parentWatchedPathInfo, Type.FINAL, event.context().getFileName().toString());
            registerDir(resolvedPath, watchedPathInfo);
            scanForFinalFiles(watchedPathInfo, resolvedPath);

            break;
          case FINAL:
            resolvedPath = watchedPath.resolve(event.context());
            if (event.context().getFileName().toString().equals(ShuffleHandler.DATA_FILE_NAME)) {
              registerFoundAttempt(parentWatchedPathInfo.pathIdentifier, null, resolvedPath);
            } else if (event.context().getFileName().toString().equals(ShuffleHandler.INDEX_FILE_NAME)) {
              registerFoundAttempt(parentWatchedPathInfo.pathIdentifier, resolvedPath, null);
            } else {
              LOG.warn("Ignoring unexpected file: " + watchedPath.resolve(event.context()));
            }
            break;
        }

      }
      if (!cancelledWatch) {
        boolean valid = watchKey.reset();
        if (!valid) {
          LOG.warn("DEBUG: WatchKey: " + watchKey.watchable() + " no longer valid");
        }
      }
    }
  }
Invoke when a pathIdentifier has been found, or is no longer of interest
@param pathIdentifier
llap-server/src/java/org/apache/hadoop/hive/llap/shufflehandler/DirWatcher.java