Spring 6.2.9
When Spring Boot auto-configures a SimpleAsyncTaskScheduler (with virtual threads enabled) to be used for running @Scheduled tasks, closing the application context will immediately interrupt the threads executing those tasks.
I was expecting the taskTerminationTimeout to be respected before hard-killing running tasks.
The offending code is here (calling Future.cancel with true):
|
for (Runnable remainingTask : this.fixedDelayExecutor.shutdownNow()) { |
|
if (remainingTask instanceof Future<?> future) { |
|
future.cancel(true); |
|
} |
|
} |
and here (explicitly calling
Thread.interrupt(), not allowing graceful completion):
|
public void close() { |
|
if (this.active) { |
|
this.active = false; |
|
Set<Thread> threads = this.activeThreads; |
|
if (threads != null) { |
|
threads.forEach(Thread::interrupt); |
|
synchronized (threads) { |
|
try { |
|
if (!threads.isEmpty()) { |
|
threads.wait(this.taskTerminationTimeout); |
|
} |
|
} |
|
catch (InterruptedException ex) { |
|
Thread.currentThread().interrupt(); |
|
} |
|
} |
|
} |
|
} |
|
} |
Note how running threads are interrupted immediately, and
then we wait for them to finish their work.
A similar issue was fixed in the past (#31019), but the fix made there doesn't help if the underlying TaskExecutor is itself also interrupting threads.
The end result is that scheduled tasks currently waiting for the database or some other service will be interrupted and fail immediately, thus preventing graceful shutdown and making the taskTerminationTimeout almost useless.
Spring 6.2.9
When Spring Boot auto-configures a
SimpleAsyncTaskScheduler(with virtual threads enabled) to be used for running@Scheduledtasks, closing the application context will immediately interrupt the threads executing those tasks.I was expecting the
taskTerminationTimeoutto be respected before hard-killing running tasks.The offending code is here (calling
Future.cancelwithtrue):spring-framework/spring-context/src/main/java/org/springframework/scheduling/concurrent/SimpleAsyncTaskScheduler.java
Lines 397 to 401 in 09a5ca3
and here (explicitly calling
Thread.interrupt(), not allowing graceful completion):spring-framework/spring-core/src/main/java/org/springframework/core/task/SimpleAsyncTaskExecutor.java
Lines 362 to 380 in 09a5ca3
Note how running threads are interrupted immediately, and then we wait for them to finish their work.
A similar issue was fixed in the past (#31019), but the fix made there doesn't help if the underlying
TaskExecutoris itself also interrupting threads.The end result is that scheduled tasks currently waiting for the database or some other service will be interrupted and fail immediately, thus preventing graceful shutdown and making the
taskTerminationTimeoutalmost useless.