Skip to content

Commit

Permalink
scheduler: add db-scheduler module
Browse files Browse the repository at this point in the history
- fix #3497
  • Loading branch information
jknack committed Sep 1, 2024
1 parent 9366f99 commit a659e14
Show file tree
Hide file tree
Showing 19 changed files with 1,762 additions and 11 deletions.
215 changes: 215 additions & 0 deletions docs/asciidoc/modules/db-scheduler.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
== db-scheduler

Task scheduler module using https://github.com/kagkarlsson/db-scheduler[db-scheduler].

=== Usage

1) Add the dependencies (hikari):

[dependency, artifactId="jooby-hikari:DataSource via HikariCP, jooby-db-scheduler:Db Scheduler Module"]
.

2) Add database driver (mySQL here):

[dependency, groupId="mysql", artifactId="mysql-connector-java", version="${mysql-connector-java.version}"]
.

3) Install DbScheduler. Add SampleJob:

.Java
[source, java, role="primary"]
----
import io.jooby.dbscheduler.DbSchedulerModule;
{
install(new HikariModule());
install(new DbSchedulerModule(Tasks.recurring(...)));
}
----

.Kotlin
[source, kt, role="secondary"]
----
import io.jooby.dbscheduler.DbSchedulerModule
{
install(DbSchedulerModule(Tasks.recurring(...)))
}
----

=== Tasks

Tasks are created as described in https://github.com/kagkarlsson/db-scheduler[db-scheduler documentation]. Optionally,
you can annotate a method with the javadoc:dbscheduler.Scheduled[] annotation:

.Sample Job
[source, java, role="primary"]
----
import io.jooby.dbscheduler.Scheduled;
public class SampleJob {
@Scheduled("1m")
public void everyMinute() {
...
}
}
----

.Kotlin
[source, kt, role="secondary"]
----
import io.jooby.dbscheduler.Scheduled
class SampleJob {
@Scheduled("1m")
fun everyMinute() : Unit {
...
}
}
----

Once you annotate your method you must create task from them with:

.Bean Tasks
[source, java]
----
import io.jooby.dbscheduler.BeanTasks;
{
install(new HikariModule());
install(new DbSchedulerModule(BeanTasks.recurring(this, SampleJob.class)));
}
----

A task method must follow these rules:

- Must be a public method
- Possible arguments: none (zero), `TaskInstance`, `ExecutionContext`, `task data` or any other application service.
- Return value: Task can return a value, which is persisted by DbScheduler. This is known as task data or task state.

=== Scheduled

The javadoc:dbscheduler.Scheduled[] annotation supports simple and cron triggers as well as property references:

.Same as .fixedDelay(Duration) with duration.
----
@Scheduled("1h")
----

.Same as .fixedDelay(Duration) with duration set to N seconds.
----
@Scheduled("FIXED_DELAY|Ns")
----

.Same as .daily(LocalTime) with optional time zone (e.g. Europe/Rome, UTC)
----
@Scheduled("DAILY|12:30,15:30...(|time_zone)")
----

.Cron, every 5 minutes
----
@Scheduled("0 0/5 * * * ?")
----

.Cron, fires every 5 minutes, at 10 seconds after the minute (i.e. 10:00:10 am, 10:05:10 am, etc.)
----
@Scheduled("10 0/5 * * * ?")
----

.Property reference
----
@Scheduled("mytask.trigger")
----

The `mytask.trigger` must be defined in your application property file. It could be a any of previous expressions.

=== Configuration

Configuration from properties files is fully supported, just need to add javadoc:dbscheduler.DbSchedulerProperties[] properties to your
application configuration file:

.Options
[source, properties]
----
# Turn on/off scheduler.
db-scheduler.enabled = true
# Set number of threads to use, default is to use the number of available processor
db-scheduler.threads = 8
db-scheduler.pollingInterval = 10s
db-scheduler.alwaysPersistTimestampInUTC = true
db-scheduler.enableImmediateExecution = false
# No need to use registerShutdownHook, the scheduler is shutdown on application shutdown
db-scheduler.registerShutdownHook = false
db-scheduler.shutdownMaxWait = 1s
----

Check more configuration options at https://github.com/kagkarlsson/db-scheduler?tab=readme-ov-file#configuration[configuration]

=== REST API

This modules comes with a simple REST API (sort of) to manage tasks:

.Scheduler API
[source, java, role="primary"]
----
import io.jooby.dbscheduler.DbSchedulerApp;
import io.jooby.dbscheduler.DbSchedulerModule;
{
install(new DbScheduler(SampleJob.class));
mount("/scheduler", new DbSchedulerApp());
}
----

.Kotlin
[source, kt, role="secondary"]
----
import io.jooby.dbscheduler.DbSchedulerApp
import io.jooby.dbscheduler.DbSchedulerModule
{
install(DbScheduler(SampleJob::class.java))
mount("/scheduler", DbSchedulerApp())
}
----

The API supports all these operations:

.List all tasks
----
GET /
----

.Running tasks
----
GET /running
----

.List tasks
----
GET /{taskName}
----

.Reschedule a task
----
GET /{taskName}/reschedule
----

.Pause schedule
----
GET /pause
----

.Resume
----
GET /resume
----

.State
----
GET /state
----
6 changes: 3 additions & 3 deletions docs/asciidoc/modules/modules.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ Available modules are listed next.
* link:/modules/thymeleaf[Thymeleaf]: Thymeleaf template engine.

=== Security
* link:/modules/jasypt[Jasypt]: Encripted configuration files.
* link:/modules/jasypt[Jasypt]: Encrypted configuration files.
* link:/modules/pac4j[Pac4j]: Security engine module.

=== Session Store
* link:/modules/caffeine[Caffeine]: In-memory session store using Caffeine cache.
* link:/modules/jwt-session-store[JWT]: JSON Web Token session store.
* link:/modules/redis#redis-http-session[Redis]: Save session data on redis.

=== Misc
* link:/modules/node[Node]: Node integration module.
=== Scheduler
* link:/modules/db-scheduler[DbScheduler]: Db scheduler module.
* link:/modules/quartz[Quartz]: Quartz scheduler module.

.
8 changes: 4 additions & 4 deletions docs/asciidoc/templates.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ Templates are available via javadoc:ModelAndView[] and requires a javadoc:Templa
[source, java, role = "primary"]
----
{
install(new MyTemplateEngineModule()); <1>
install(new MyTemplateEngineModule()); <1>
get("/", ctx -> {
MyModel model = ...; <2>
MyModel model = ...; <2>
return new ModelAndView("index.html", model); <3>
});
}
Expand All @@ -22,8 +22,8 @@ Templates are available via javadoc:ModelAndView[] and requires a javadoc:Templa
install(MyTemplateEngineModule()) <1>
get("/") { ctx ->
val model = MyModel(...) <2>
ModelAndView("index.html", model) <3>
val model = MyModel(...) <2>
ModelAndView("index.html", model) <3>
}
}
----
Expand Down
4 changes: 2 additions & 2 deletions docs/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
<version>0.10.0</version>
<version>0.10.1</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -100,7 +100,7 @@
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.1.0</version>
<version>3.4.1</version>
<executions>
<execution>
<id>asciidoctor</id>
Expand Down
4 changes: 2 additions & 2 deletions docs/src/main/java/io/jooby/adoc/DocGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public static void generate(Path basedir, boolean publish, boolean v1, boolean d
int adocCount =
Stream.of(treeDirs)
.map(throwingFunction(dir -> countAdoc(asciidoc.resolve(dir))))
.reduce(1, (a, b) -> a + b);
.reduce(1, Integer::sum);
int steps = 7 + (doAscii ? adocCount : 0);

ProgressBarBuilder pbb =
Expand All @@ -71,7 +71,7 @@ public static void generate(Path basedir, boolean publish, boolean v1, boolean d
.setInitialMax(steps)
.setTaskName("Building Site");

try (ProgressBar pb = pbb.build()) {
try (var pb = pbb.build()) {

Path outdir = asciidoc.resolve("site");
if (!Files.exists(outdir)) {
Expand Down
5 changes: 5 additions & 0 deletions modules/jooby-bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@
<artifactId>jooby-conscrypt</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby-db-scheduler</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby-distribution</artifactId>
Expand Down
43 changes: 43 additions & 0 deletions modules/jooby-db-scheduler/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<parent>
<groupId>io.jooby</groupId>
<artifactId>modules</artifactId>
<version>3.2.10-SNAPSHOT</version>
</parent>

<modelVersion>4.0.0</modelVersion>
<artifactId>jooby-db-scheduler</artifactId>

<dependencies>
<dependency>
<groupId>io.jooby</groupId>
<artifactId>jooby</artifactId>
<version>${jooby.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.github.kagkarlsson/db-scheduler -->
<dependency>
<groupId>com.github.kagkarlsson</groupId>
<artifactId>db-scheduler</artifactId>
<version>14.0.3</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.agent</artifactId>
<classifier>runtime</classifier>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Loading

0 comments on commit a659e14

Please sign in to comment.