From 71fb9ef4f1342b35f5b4e012f0b5fbf3120a5613 Mon Sep 17 00:00:00 2001 From: Daniele Gaffuri Date: Sun, 7 Sep 2025 09:45:01 +0200 Subject: [PATCH 1/2] Fix quarkus.thread-pool.shutdown-interrupt (#49733) --- .../main/java/io/quarkus/runtime/ExecutorRecorder.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java b/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java index cc275c5ceac4c..d70f6e574180d 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java @@ -79,10 +79,12 @@ public void run() { executor.shutdown(); final Duration shutdownTimeout = threadPoolConfig.shutdownTimeout(); final Optional optionalInterval = threadPoolConfig.shutdownCheckInterval(); - long remaining = shutdownTimeout.toNanos(); + final long shutdownRemaining = shutdownTimeout.toNanos(); + long remaining = shutdownRemaining; final long interval = optionalInterval.orElse(Duration.ofNanos(Long.MAX_VALUE)).toNanos(); long intervalRemaining = interval; - long interruptRemaining = threadPoolConfig.shutdownInterrupt().toNanos(); + final long interrupt = threadPoolConfig.shutdownInterrupt().toNanos(); + long interruptRemaining = interrupt; long start = System.nanoTime(); int loop = 1; @@ -94,8 +96,8 @@ public void run() { if (!executor.awaitTermination(Math.min(remaining, intervalRemaining), TimeUnit.NANOSECONDS)) { long elapsed = System.nanoTime() - start; intervalRemaining -= elapsed; - remaining -= elapsed; - interruptRemaining -= elapsed; + remaining = shutdownRemaining - elapsed; + interruptRemaining = interrupt - elapsed; if (interruptRemaining <= 0) { executor.shutdown(true); } From 5d2d8633e515ad70c0959f52c0754338df6d6b0d Mon Sep 17 00:00:00 2001 From: Daniele Gaffuri Date: Mon, 8 Sep 2025 14:06:33 +0200 Subject: [PATCH 2/2] Fix variable names --- .../io/quarkus/runtime/ExecutorRecorder.java | 37 +++++++++---------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java b/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java index d70f6e574180d..2e508f948763e 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/ExecutorRecorder.java @@ -2,7 +2,6 @@ import java.time.Duration; import java.util.List; -import java.util.Optional; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadFactory; @@ -77,31 +76,31 @@ private static Runnable createShutdownTask(ThreadPoolConfig threadPoolConfig, En @Override public void run() { executor.shutdown(); - final Duration shutdownTimeout = threadPoolConfig.shutdownTimeout(); - final Optional optionalInterval = threadPoolConfig.shutdownCheckInterval(); - final long shutdownRemaining = shutdownTimeout.toNanos(); - long remaining = shutdownRemaining; - final long interval = optionalInterval.orElse(Duration.ofNanos(Long.MAX_VALUE)).toNanos(); - long intervalRemaining = interval; - final long interrupt = threadPoolConfig.shutdownInterrupt().toNanos(); - long interruptRemaining = interrupt; + final long configShutdownTimeout = threadPoolConfig.shutdownTimeout().toNanos(); + final long configShutdownInterrupt = threadPoolConfig.shutdownInterrupt().toNanos(); + final long configShutdownCheckInterval = threadPoolConfig.shutdownCheckInterval() + .orElse(Duration.ofNanos(Long.MAX_VALUE)).toNanos(); + long shutdownTimeout = configShutdownTimeout; + long shutdownInterrupt = configShutdownInterrupt; + long shutdownCheckInterval = configShutdownCheckInterval; long start = System.nanoTime(); int loop = 1; for (;;) { // This log can be very useful when debugging problems - log.debugf("loop: %s, remaining: %s, intervalRemaining: %s, interruptRemaining: %s", loop++, remaining, - intervalRemaining, interruptRemaining); + log.debugf("loop: %s, shutdownTimeout: %s, shutdownCheckInterval: %s, shutdownInterrupt: %s", loop++, + shutdownTimeout, shutdownCheckInterval, shutdownInterrupt); try { - if (!executor.awaitTermination(Math.min(remaining, intervalRemaining), TimeUnit.NANOSECONDS)) { + if (!executor.awaitTermination(Math.min(shutdownTimeout, shutdownCheckInterval), + TimeUnit.NANOSECONDS)) { long elapsed = System.nanoTime() - start; - intervalRemaining -= elapsed; - remaining = shutdownRemaining - elapsed; - interruptRemaining = interrupt - elapsed; - if (interruptRemaining <= 0) { + shutdownTimeout = configShutdownTimeout - elapsed; + shutdownInterrupt = configShutdownInterrupt - elapsed; + shutdownCheckInterval = configShutdownCheckInterval - elapsed; + if (shutdownInterrupt <= 0) { executor.shutdown(true); } - if (remaining <= 0) { + if (shutdownTimeout <= 0) { // done waiting final List runnables = executor.shutdownNow(); if (!runnables.isEmpty()) { @@ -113,8 +112,8 @@ public void run() { } break; } - if (intervalRemaining <= 0) { - intervalRemaining = interval; + if (shutdownCheckInterval <= 0) { + shutdownCheckInterval = configShutdownCheckInterval; // do some probing final int queueSize = executor.getQueueSize(); final Thread[] runningThreads = executor.getRunningThreads();