QueryInfo queryComplete(QueryIdentifier queryIdentifier, long deleteDelay,
      boolean isExternalQuery) throws IOException {
    if (deleteDelay == -1) {
      deleteDelay = defaultDeleteDelaySeconds;
    }
    ReadWriteLock dagLock = getDagLock(queryIdentifier);
    dagLock.writeLock().lock();
    try {
      // If isExternalQuery -> the call is from within hte daemon, so no permission check required
      // to get access to the queryInfo instance.
      QueryInfo queryInfo = isExternalQuery
          ? queryInfoMap.get(queryIdentifier) : checkPermissionsAndGetQuery(queryIdentifier);
      if (queryInfo == null) {
        // Should not happen.
        LOG.warn("Ignoring query complete for unknown dag: {}", queryIdentifier);
        return null;
      }

      LOG.info(
          "Processing queryComplete for queryIdentifier={}, isExternalQuery={}, with deleteDelay={} seconds",
          queryIdentifier, isExternalQuery,
          deleteDelay);

      queryInfoMap.remove(queryIdentifier);
      if (!isExternalQuery) {
        rememberCompletedDag(queryIdentifier);
        cleanupLocalDirs(queryInfo, deleteDelay);
        handleLogOnQueryCompletion(queryInfo.getHiveQueryIdString(), queryInfo.getDagIdString());
      } else {
        // If there's no pending fragments, queue some of the cleanup for a later point - locks, log rolling.
        if (queryInfo.getRegisteredFragments().size() == 0) {
          LOG.debug("Queueing future cleanup for external queryId: {}", queryInfo.getHiveQueryIdString());
          executorService.schedule(new ExternalQueryCleanerCallable(queryInfo.getHiveQueryIdString(),
                  queryInfo.getDagIdString(), queryInfo.getQueryIdentifier()), 1, TimeUnit.MINUTES);
        } else {
          if (LOG.isTraceEnabled()) {
            LOG.trace(
                "NumRegisterFragments={}, Not queuing cleanup for external queryId={}",
                queryInfo.getRegisteredFragments().size(), queryInfo.getHiveQueryIdString());
          }
        }
      }

      // Clearing this before sending a kill is OK, since canFinish will change to false.
      // Ideally this should be a state machine where kills are issued to the executor,
      // and the structures are cleaned up once all tasks complete. New requests, however,
      // should not be allowed after a query complete is received.
      sourceCompletionMap.remove(queryIdentifier);
      String savedQueryId = queryIdentifierToHiveQueryId.remove(queryIdentifier);
      if (!isExternalQuery) {
        removeQuerySpecificLock(queryIdentifier);
      }
      if (savedQueryId != null) {
        ObjectCacheFactory.removeLlapQueryCache(savedQueryId);
      }
      return queryInfo;
    } finally {
      dagLock.writeLock().unlock();
    }
  }
Register completion for a query
@param queryIdentifier
@param deleteDelay
llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/QueryTracker.java