Although many examples won't make much sense without demonstrating the
use of triggers, this guide will focus more on jobs and related
scheduler operations, while the dedicated guide on triggers will focus more on using various
kinds of schedules.

What version of Quartzite does this guide cover?

This guide covers Quartzite 2.0.x (including beta releases).

Overview

Quartz separates operations that are performed (called jobs) from
rules according to which they are performed (triggers). Triggers
combine execution schedule (for example, "every 4 hours" or "at noon
every Friday"), date/time when execution starts and ends, operation
priority and a few other things.

A job may have multiple triggers associated with them (although it is
common to have just one). Both jobs and triggers have identifiers
(called "keys") that you use to manage them, for example, unschedule,
pause or resume.

Defining Quartz jobs with a Clojure DSL

Jobs in Quartz are objects that implement org.quartz.Job, a single
function interface. One way to define a job is to define a record that
implements that interface:

This does not look very Clojuric, does it. Because jobs are single
method interfaces, it makes perfect sense to use Clojure functions as
jobs. Unfortunately, due to certain Quartz implementation details and
the way Clojure loads generated classes, many approaches to using
functions do not work.

Quartzite provides a macro that makes defining jobs more concise but
avoids limitations of using proxies and reification. The macro is
clojurewerkz.quartzite.jobs/defjob:

These examples demonstrate defining the "executable part" of a job. As
we've mentioned before, to make it possible to manage jobs and
triggers, Quartz requires them to have identities. To define a
complete job that can be submitted for scheduling, you use a DSL in
the clojurewerkz.quartzite.jobs namespace:

clojurewerkz.quartzite.jobs/key function can be used with any other function that accepts job keys.

Using keys to identify jobs

In order to pause or completely remove a job from the scheduler, there
needs to be a way to identify it. Job identifiers are called "keys". A
key consists of a string identifier and an (optional) group. To
instantiate keys, use clojurewerkz.quartzite.jobs/key function:

(nsquartzite.docs.examples(:require[clojurewerkz.quartzite.scheduler:asqs][clojurewerkz.quartzite.jobs:asj])(:importjava.util.UUID));; this key uses the default group
;; and features account id in the identifier (to guarantee uniqueness)
(j/key"invoices.102");; this key uses a custom group
;; and uses a random UUID as the identifier
(j/key(str(UUID/randomUUID))"aggregators")

When group is not specified, the default group is used. It is common
to use groups to "namespace" executed jobs, for example, to separate
operations that perform periodic data aggregation from those that
generate invoices.

Jobs contexts and job data maps

Many jobs will need some kind of context to carry out their
duties. For example, an aggregation job associated with a particular
account will need that account's id in order to load it from a data
store. A job that involves retrieving Web pages may need the URL to
use and so on.

When Quartz executes a job, it will pass it a job context object
that among other things, includes arbitrary data that the job needs.

Lets take a look at a simplest Quartzite job possible:

(defjobNoOpJob[ctx](comment"Does nothing"))

It takes the aforementioned job context which is an instance of
JobExecutionContext.
The job execution context you can retrieve job data map. Quartzite
offers a function that returns job data map as an immutable
Clojure map:

If the scheduler is started, execution begins according to the start
moment of the submitted trigger. In the example above, the trigger
will fire 10 times every 200 ms and expire after that. Expired
triggers do not execute associated jobs.

Unscheduling jobs

To unschedule an operation, you unschedule its trigger (or several of
them) using clojurewerkz.quartzite.scheduler/unschedule-job and
clojurewerkz.quartzite.scheduler/unschedule-jobs functions:

Pausing and resuming jobs

Jobs can be paused and resumed. Pausing a job pauses all of its
triggers so the job won't be executed but is not removed from the
scheduler. To pause a single job, use
clojurewerkz.quartzite.scheduler/pause-job and pass it the job's
key:

clojurewerkz.quartzite.scheduler/pause-jobs will pause one or
several groups of jobs by pausing their triggers. What groups are
paused is determined by the group matcher, instantiated via Java
interop:

(nsmy.service(:require[clojurewerkz.quartzite.scheduler:asqs][clojurewerkz.quartzite.jobs:asj][clojurewerkz.quartzite.jobs:refer[defjob]])(:importorg.quartz.impl.matchers.GroupMatcher))(defjobNoOpJob[ctx](comment"Does nothing"))(defn-main[&m](let[s(->(qs/initialize)qs/start)matcher(GroupMatcher/groupEquals"billing")];; pause a group of jobs
(qs/pause-jobssmatcher)))

In addition to the exact matcher, there are several other matchers available:

clojurewerkz.quartzite.scheduler/resume-jobs resumes one or more job
groups using the already covered group matchers:

(nsmy.service(:require[clojurewerkz.quartzite.scheduler:asqs][clojurewerkz.quartzite.jobs:asj])(:use[clojurewerkz.quartzite.jobs:only[defjob]])(:importorg.quartz.impl.matchers.GroupMatcher))(defjobNoOpJob[ctx](comment"Does nothing"))(defn-main[&m](let[s(->(qs/initialize)qs/start)];; resumes a group of jobs
(qs/resume-jobss(GroupMatcher/groupEquals"billing"))))

Finally, clojurewerkz.quartzite.scheduler/pause-all! and
clojurewerkz.quartzite.scheduler/resume-all! are functions that
pause and resume the entire scheduler. Use them carefully. Both take
no arguments.

Jobs and Trigger Misfires

A misfire occurs if a persistent trigger "misses" its firing time
because of being paused, the scheduler being shutdown, or because
there are no available threads in Quartz's thread pool for executing
the job. When a job is resumed, if any of its triggers have missed one
or more fire-times, the trigger's misfire instruction will apply.

Completely removing jobs from the scheduler

It is possible to completely remove a job from the scheduler. Doing so
will also remove all the associated triggers. The job will never be
executed again (unless it is
re-scheduled). clojurewerkz.quartzite.scheduler/delete-job deletes a
single job by job key: