@Override
  public void serviceStart() {
    QueueLookupCallable queueDrainerCallable = new QueueLookupCallable();
    queueLookupFuture = queueLookupExecutor.submit(queueDrainerCallable);
    Futures.addCallback(queueLookupFuture, new FutureCallback<Void>() {
      @Override
      public void onSuccess(Void result) {
        LOG.info("AMReporter QueueDrainer exited");
      }

      @Override
      public void onFailure(Throwable t) {
        if (t instanceof CancellationException && isShutdown.get()) {
          LOG.info("AMReporter QueueDrainer exited as a result of a cancellation after shutdown");
        } else {
          LOG.error("AMReporter QueueDrainer exited with error", t);
          Thread.getDefaultUncaughtExceptionHandler().uncaughtException(Thread.currentThread(), t);
        }
      }
    }, MoreExecutors.directExecutor());
    // TODO: why is this needed? we could just save the host and port?
    nodeId = LlapNodeId.getInstance(localAddress.get().getHostName(), localAddress.get().getPort());
    LOG.info("AMReporter running with DaemonId: {}, NodeId: {}", daemonId, nodeId);
  }
Responsible for communicating with various AMs.
llap-server/src/java/org/apache/hadoop/hive/llap/daemon/impl/AMReporter.java