Quartz is a job schedule plugin for Grails, sort of like a plugin for cron job. To use it:
autoStartup: true
in application.yml under section quartz:create-job
command to create the skeleton of the job file.We only cover enough to use information here, for more details, it is always good to visit the official site of Quartz plugin for Grails
In build.gradle dependencies section, add quartz. Depending on the version of Grails, for Grails version 3.3.x, you can use quartz 2.0.13, otherwise you MUST stay with quartz 2.0.1
compile 'org.grails.plugins:quartz:2.0.1'
or
compile 'org.grails.plugins:quartz:2.0.13'
In application.yml, add a new root section quartz like:
quartz: autoStartup: true
Quartz will then auto start up when the app is being started.
In Grails console:
grails> create-job printlnEveryFiveSecond | Rendered template Job.groovy to destination grails-app\jobs\testcsv\PrintlnEveryFiveSecondJob.groovy
Note that the the command will automatically add “Job” at the end of your class name.
The job class contains two things, the triggers
and the execute
methods. When this class is being triggered, the execute method will be called. It is possible to inject service instance in this class so that you can call the service in the execute method.
class PrintlnEveryFiveSecondJob { static triggers = { simple repeatInterval: 5000l // execute job once in 5 seconds } def execute() { // execute job println("hi") } }
Repeat it every 5 seconds
static triggers = { simple repeatInterval: 5000l // execute job once in 5 seconds }
Repeat it every 5 seconds in cron style
static triggers = { cron name: 'schedulingTasks', cronExpression: "/5 * * * * ?" }
Repeat it every day at 02:00:00 AM
static triggers = { cron name: 'schedulingTasks', cronExpression: "0 0 2 * * ?" }
For more details, go see the Documentation of Quartz plugin.
To make sure the same job does not concurrently running more than one time, you can add static concurrent = false
in the job class.
Note that quartz plugin does not support clustering by default. Additional work are needed to do so. Assume we have a task that done daily. One of the simple way is to have a database with a unique column value that store the date in format “YYYY-MM-DD”, and only the node on the cluster able to write this value is allowed to execute the job. Of course, you need to do this checking inside the execute function like:
def execute() { Date now = DateTimeTools.getSystemCurrentTime() try { CronRecord cr = new CronRecord() cr.date = (new SimpleDateFormat("yyyy-MM-dd")).format(now) cr.save(failOnError: true) } catch (Exception ignored) { //if it cannot be save, meaning that someone has already done it. return } //TODO: continue your job here . . . }