presto-main/src/main/java/io/prestosql/server/GracefulShutdownHandler.java/GracefulShutdownHandler/requestShutdown
class GracefulShutdownHandler:    public synchronized void requestShutdown()
    {
        log.info("Shutdown requested");

        if (isCoordinator) {
            throw new UnsupportedOperationException("Cannot shutdown coordinator");
        }

        if (isShutdownRequested()) {
            return;
        }

        setShutdownRequested(true);

        //wait for a grace period to start the shutdown sequence
        shutdownHandler.schedule(() -> {
            List<TaskInfo> activeTasks = getActiveTasks();
            while (activeTasks.size() > 0) {
                CountDownLatch countDownLatch = new CountDownLatch(activeTasks.size());

                for (TaskInfo taskInfo : activeTasks) {
                    sqlTaskManager.addStateChangeListener(taskInfo.getTaskStatus().getTaskId(), newState -> {
                        if (newState.isDone()) {
                            countDownLatch.countDown();
                        }
                    });
                }

                log.info("Waiting for all tasks to finish");

                try {
                    countDownLatch.await();
                }
                catch (InterruptedException e) {
                    log.warn("Interrupted while waiting for all tasks to finish");
                    currentThread().interrupt();
                }

                activeTasks = getActiveTasks();
            }

            // wait for another grace period for all task states to be observed by the coordinator
            sleepUninterruptibly(gracePeriod.toMillis(), MILLISECONDS);

            Future<?> shutdownFuture = lifeCycleStopper.submit(() -> {
                lifeCycleManager.stop();
                return null;
            });

            // terminate the jvm if life cycle cannot be stopped in a timely manner
            try {
                shutdownFuture.get(LIFECYCLE_STOP_TIMEOUT.toMillis(), MILLISECONDS);
            }
            catch (TimeoutException e) {
                log.warn(e, "Timed out waiting for the life cycle to stop");
            }
            catch (InterruptedException e) {
                log.warn(e, "Interrupted while waiting for the life cycle to stop");
                currentThread().interrupt();
            }
            catch (ExecutionException e) {
                log.warn(e, "Problem stopping the life cycle");
            }

            shutdownAction.onShutdown();
        }, gracePeriod.toMillis(), MILLISECONDS);
    }