Replacing quartz with db-scheduler
I was recently tasked with replacing quartz with a simpler solution, db-scheduler was the library I chose because was a good fit, it was simple, the task are easy to configure and only 1 table is needed in the database.
The first thing I did was add the dependency to my spring boot project
<dependency>
<groupId>com.github.kagkarlsson</groupId>
<artifactId>db-scheduler</artifactId>
<version>10.3</version>
</dependency>
In the repository there is a spring boot starter project
I copied the configuration classes to my own project and made some changes to suit my needs for example i didn’t want tasks to start by default so I changed Scheduler scheduler
@ConditionalOnBean(DataSource.class)
@ConditionalOnMissingBean
@Bean(destroyMethod = "stop")
public Scheduler scheduler(DbSchedulerCustomizer customizer, StatsRegistry registry) {
...
final SchedulerBuilder builder = Scheduler.create(transactionalDataSource, nonStartupTasks(configuredTasks));
// to
final SchedulerBuilder builder = Scheduler.create(transactionalDataSource, configuredTasks);
...
}
@ConditionalOnBean(DataSource.class)
@ConditionalOnMissingBean
@Bean(destroyMethod = "stop")
public Scheduler scheduler(DbSchedulerCustomizer customizer, StatsRegistry registry) {
...
builder.startTasks(startupTasks(configuredTasks)); // removed
...
}
And then I added the default settings to my application.properties
# Db-scheduler configuration
db-scheduler.threads=5
db-scheduler.polling-interval=5s
db-scheduler.polling-strategy=fetch
db-scheduler.polling-strategy-lower-limit-fraction-of-threads=0.5
db-scheduler.polling-strategy-upper-limit-fraction-of-threads=3.0
I configured all tasks and then made another service in wich I inject the scheduler and the List<Task>
tasks
to schedule, pause and cancel tasks;
package com.exampletasks.demo.configuration;
import com.github.kagkarlsson.scheduler.task.Task;
import com.github.kagkarlsson.scheduler.task.helper.Tasks;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.time.Duration;
import static com.github.kagkarlsson.scheduler.task.schedule.Schedules.fixedDelay;
@Configuration
public class TaskConfiguration {
private static final Logger log = LoggerFactory.getLogger(TaskConfiguration.class);
@Bean
Task<Void> recurringSampleTask() {
Task task = Tasks
.recurring("recurring-sample-task", fixedDelay(Duration.ofMinutes(1)))
.execute((instance, ctx) -> {
log.info("Running recurring-simple-task. Instance: {}, ctx: {}", instance, ctx);
});
return task;
}
}
I needed to implement my own schedule to schedule recurring tasks each month
package com.bitfarm.ibox.model.task;
import com.github.kagkarlsson.scheduler.task.ExecutionComplete;
import com.github.kagkarlsson.scheduler.task.schedule.Schedule;
import java.time.*;
public class MonthlySchedule implements Schedule {
@Override
public Instant getNextExecutionTime(ExecutionComplete executionComplete) {
ZoneId systemZone = ZoneId.systemDefault();
LocalDateTime date = executionComplete.getTimeDone().atZone(systemZone).toLocalDateTime().plusMonths(1);
Instant instant = date.atZone(systemZone).toInstant();
return instant;
}
@Override
public boolean isDeterministic() {
return false;
}
}