Commits
Tarun Sukhani authored 04e84268276
fix: drain scheduler queue in VTSE.shutdownGracefully (release 1.12.13)
PF-60: scheduleWithFixedDelay's self-rescheduling chain leaves a one-shot
delayed task in the STPE queue between runs. STPE's default
executeExistingDelayedTasksAfterShutdownPolicy(true) keeps queued one-shots
alive across shutdown(), so awaitTermination cannot return until each
queued dispatch's delay elapses. With any @Every("24h")-style job,
JobsPlugin.onApplicationStop deterministically hit the stop-timeout budget
and emitted "Jobs scheduler did not terminate within 30000 ms" on every
clean shutdown.
shutdownGracefully now calls scheduler.shutdownNow() to drain queued
dispatches immediately, then waits only for in-flight virtual-thread work
on the virtualExecutor. Cancelled queued dispatches surface as
RejectedExecutionException on the next self-reschedule, which the
existing periodic lambda already converts to handle.cancel(false), so
periodic-future consumers still see a terminal state.
The H1 test (scheduleWithFixedDelayShutdownBetweenRunsDrainsHandle) is
unaffected — it exercises shutdownScheduler(), a separate path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>