diff --git a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzBuildTimeConfig.java b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzBuildTimeConfig.java index f6399895ba720..fa9fa7dbfb07c 100644 --- a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzBuildTimeConfig.java +++ b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzBuildTimeConfig.java @@ -1,5 +1,6 @@ package io.quarkus.quartz.runtime; +import java.time.Duration; import java.util.Map; import java.util.Optional; @@ -57,6 +58,13 @@ public class QuartzBuildTimeConfig { @ConfigItem(defaultValue = "QRTZ_") public String tablePrefix; + /** + * The maximum amount of time Quarkus will wait for currently running jobs to finish. + * If the value is {@code 0}, then Quarkus will not wait at all for these jobs to finish. + */ + @ConfigItem(defaultValue = "10") + public Duration shutdownWaitTime; + /** * The SQL string that selects a row in the "LOCKS" table and places a lock on the row. *

diff --git a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java index 17812724b7dae..3ce08a897829f 100644 --- a/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java +++ b/extensions/quartz/runtime/src/main/java/io/quarkus/quartz/runtime/QuartzScheduler.java @@ -11,7 +11,10 @@ import java.util.Objects; import java.util.OptionalLong; import java.util.Properties; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Collectors; import javax.annotation.PreDestroy; @@ -89,6 +92,7 @@ public class QuartzScheduler implements Scheduler { private final org.quartz.Scheduler scheduler; private final boolean enabled; private final boolean startHalted; + private final Duration shutdownWaitTime; private final Map scheduledTasks = new HashMap<>(); public QuartzScheduler(SchedulerContext context, QuartzSupport quartzSupport, SchedulerRuntimeConfig schedulerRuntimeConfig, @@ -97,6 +101,7 @@ public QuartzScheduler(SchedulerContext context, QuartzSupport quartzSupport, Sc Vertx vertx) { enabled = schedulerRuntimeConfig.enabled; final Duration defaultOverdueGracePeriod = schedulerRuntimeConfig.overdueGracePeriod; + shutdownWaitTime = quartzSupport.getBuildTimeConfig().shutdownWaitTime; final QuartzRuntimeConfig runtimeConfig = quartzSupport.getRuntimeConfig(); boolean forceStart; @@ -478,9 +483,24 @@ void start(@Observes @Priority(Interceptor.Priority.PLATFORM_BEFORE) StartupEven void destroy(@Observes @BeforeDestroyed(ApplicationScoped.class) Object event) { if (scheduler != null) { try { - // Note that this method does not return until all currently executing jobs have completed - scheduler.shutdown(true); - } catch (SchedulerException e) { + if (shutdownWaitTime.isZero()) { + scheduler.shutdown(false); + } else { + CompletableFuture.supplyAsync(new Supplier<>() { + @Override + public Void get() { + // Note that this method does not return until all currently executing jobs have completed + try { + scheduler.shutdown(true); + } catch (SchedulerException e) { + throw new RuntimeException(e); + } + return null; + } + }).get(shutdownWaitTime.toMillis(), TimeUnit.MILLISECONDS); + } + + } catch (Exception e) { LOGGER.warnf("Unable to gracefully shutdown the scheduler", e); } }