Source:
<code>public synchronized void requestShutdown() { log.info("Shutdown requested"); if (isCoordinator) { throw new UnsupportedOperationException("Cannot shutdown coordinator"); } if (isShutdownRequested()) { return; } setShutdownRequested(true); shutdownHandler.schedule(() -> { List<TaskInfo> activeTasks = getActiveTasks(); <START> while (activeTasks.size() > 0) { <END> CountDownLatch countDownLatch = new CountDownLatch(activeTasks.size()); for (TaskInfo taskInfo : activeTasks) { if (cancelShutdown()) { unsetShutdownFlagOnCancel(); return; } 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(); } sleepUninterruptibly(gracePeriod.toMillis(), MILLISECONDS); if (!cancelShutdown()) { Future<?> shutdownFuture = lifeCycleStopper.submit(() -> { lifeCycleManager.stop(); return null; }); 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(); } else { unsetShutdownFlagOnCancel(); return; } }, gracePeriod.toMillis(), MILLISECONDS); }</code><technical_language>unnecessary change</technical_language>

Target:
public synchronized void requestShutdown() { log.info("Shutdown requested"); if (isCoordinator) { throw new UnsupportedOperationException("Cannot shutdown coordinator"); } if (isShutdownRequested()) { return; } setShutdownRequested(true); shutdownTaskFuture = shutdownHandler.schedule(() -> { shutdownAction.onShutdownStart(); 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"); synchronized (GracefulShutdownHandler.this) { if (cancelShutdown) { log.warn("Not waiting any longer for tasks to finish as request was made to cancel shutdown"); cancelShutdown = false; shutdownAction.onCancelWaitForTasksToComplete(); currentThread().interrupt(); return; } } currentThread().interrupt(); } activeTasks = getActiveTasks(); } synchronized (GracefulShutdownHandler.this) { if (cancelShutdown) { shutdownAction.onCancelJVMShutdown(); log.warn("Skipping JVM shutdown since request was made to cancel shutdown"); cancelShutdown = false; return; } } sleepUninterruptibly(gracePeriod.toMillis(), MILLISECONDS); Future<?> stopLifeCycleFuture = lifeCycleStopper.submit(() -> { lifeCycleManager.stop(); return null; }); try { stopLifeCycleFuture.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.onShutdownComplete(); }, 0, MILLISECONDS); }