/**
   * Executors are only closed if they were not supplied externally in the {@link
   * org.apache.tinkerpop.gremlin.groovy.engine.GremlinExecutor.Builder}
   */
  public CompletableFuture<Void> closeAsync() throws Exception {
    final CompletableFuture<Void> future = new CompletableFuture<>();

    new Thread(
            () -> {
              // leave pools running if they are supplied externally.  let the sender be responsible
              // for shutting them down
              if (!suppliedExecutor) {
                executorService.shutdown();
                try {
                  if (!executorService.awaitTermination(180000, TimeUnit.MILLISECONDS))
                    logger.warn(
                        "Timeout while waiting for ExecutorService of GremlinExecutor to shutdown.");
                } catch (InterruptedException ie) {
                  logger.warn(
                      "ExecutorService on GremlinExecutor may not have shutdown properly as shutdown thread terminated early.");
                }
              }

              // calls to shutdown are idempotent so no problems calling it twice if the pool is
              // shared
              if (!suppliedScheduledExecutor) {
                scheduledExecutorService.shutdown();
                try {
                  if (!scheduledExecutorService.awaitTermination(180000, TimeUnit.MILLISECONDS))
                    logger.warn(
                        "Timeout while waiting for ScheduledExecutorService of GremlinExecutor to shutdown.");
                } catch (InterruptedException ie) {
                  logger.warn(
                      "ScheduledExecutorService on GremlinExecutor may not have shutdown properly as shutdown thread terminated early.");
                }
              }

              try {
                scriptEngines.close();
              } catch (Exception ex) {
                logger.warn(
                    "Error while shutting down the ScriptEngines in the GremlinExecutor", ex);
              }

              future.complete(null);
            },
            "gremlin-executor-close")
        .start();

    return future;
  }