Quartz workflow scheduler

The Serverless Workflow specification allows you to define workflows that execute automatically on a recurring schedule.

By default, the ServerlessWorkflow SDK engine uses a lightweight, in-memory implementation (based on ScheduledExecutorService and the cron-utils library) to trigger these executions. Additionally, Quakus flow provides a native Quarkus scheduler for stand alone deployments. However, for a production-grade Quarkus application deployed in multiple clusters, persistence Quartz scheduler must be used to guarantee proper function. The contrary is also true, you must not use this one for stand alone deployments.

This guide shows how to:

  • Enable the Quartz Flow Scheduler.

  • Define a recurring schedule in your workflow.

Prerequisites

1. Add the Quartz Scheduler dependency

To replace the default engine scheduler with the Quartz Scheduler, first step is to add the quarkus-flow-quartz-scheduler extension to your project.

pom.xml
<dependency>
   <groupId>io.quarkiverse.flow</groupId>
   <artifactId>quarkus-flow-quartz-scheduler</artifactId>
   <version>${project.version}</version>
</dependency>

Adding this dependency automatically wires Quarkus Flow to use the underlying Quarkus Quartz scheduling infrastructure. This gives you access to robust application lifecycle management and all standard Quarkus Scheduler configuration properties.

Quarkus Quartz scheduler requires persistence to properly function in a clustered environment. Currently Quarkus Quartz only supports relational DB. Quarkus Flow provides a Flyway script that contains the definition of the tables required by quarkus. In order your Quarkus application to enable persistence for Quartz and use that script to automatically create the tables, you need to add following configuration to your application.properties file.

application.properties
# Quartz configuration
quarkus.quartz.clustered=true
quarkus.quartz.store-type=jdbc-cmt
quarkus.quartz.misfire-policy.task-job=ignore-misfire-policy

# flyway configuration
quarkus.flyway.connect-retries=10
quarkus.flyway.table=flyway_quarkus_history
quarkus.flyway.migrate-at-start=true
quarkus.flyway.baseline-on-migrate=true
quarkus.flyway.baseline-version=1.0
quarkus.flyway.baseline-description=Quartz

In addition to these properties, you need to setup your DB connection details and driver as indicated in Quarkus Datasource guide. For example,for a postgresql DB, you will need to update your application.properties and pom.xml files in the following way:

application.properties
# Datasource configuration.
quarkus.datasource.db-kind=postgresql
quarkus.datasource.username=<replace with your postgresql user>
quarkus.datasource.password=<replace with your postgresql password >
quarkus.datasource.jdbc.url=jdbc:postgresql://<replace with db host name>/<replace with your database name>
pom.xml
<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>

2. Define a schedule in your workflow

You can define a schedule directly in your workflow definition. The specification supports three scheduling formats:

  • cron: A Quartz CRON expression.

  • every: An ISO-8601 duration (e.g., PT15M for every 15 minutes) representing the interval between executions.

  • after: An ISO-8601 duration representing a delay before the workflow starts.

Example: YAML Definition

Here is an example of a workflow that executes automatically every second using a CRON expression:

document:
  dsl: '1.0.0'
  namespace: org.acme
  name: ScheduledJob
  version: '1.0'
schedule:
  cron: "* * * * * ?"
do:
  - runTask:
      call: http
      with:
        method: POST
        endpoint: "https://api.example.com/sync"

Quartz cron format

The Serverless Workflow specification mandates that CRON expressions follow the standard Unix format.

The Quarkus Quartz Scheduler, however, use the Quartz format. This means that, if you are using the Unix format in your workflow definition, you should change the CRON expression to use Quartz format.

See also