Skip to content

Commit

Permalink
Use a timer when awaiting Quartz shutdown
Browse files Browse the repository at this point in the history
The Quartz scheduler shutdown seems like it
can block indefinitely if there is an exception
in a yet to be completed job.
To guard against this, we ensure that we only
wait a configurable amount of time for the scheduler
to shut down.

This is a breaking change because previously we waited
indefinitely.

Relates to quarkusio#28114

Co-authored-by: Manyanda Chitimbo <manyanda.chitimbo@gmail.com>
  • Loading branch information
geoand and machi1990 committed Sep 26, 2022
1 parent 0034efe commit 5487f50
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
@@ -1,5 +1,6 @@
package io.quarkus.quartz.runtime;

import java.time.Duration;
import java.util.Map;
import java.util.Optional;

Expand Down Expand Up @@ -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.
* <p>
Expand Down
Expand Up @@ -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;
Expand Down Expand Up @@ -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<String, QuartzTrigger> scheduledTasks = new HashMap<>();

public QuartzScheduler(SchedulerContext context, QuartzSupport quartzSupport, SchedulerRuntimeConfig schedulerRuntimeConfig,
Expand All @@ -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;
Expand Down Expand Up @@ -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);
}
}
Expand Down

0 comments on commit 5487f50

Please sign in to comment.