Scheduler

Contents

Named tasks can be scheduled to asynchronously run in the background in a cluster or a one-node environment.

Scheduled Job

A scheduled job is an object which describes how a named task must be run. It contains information about the type of scheduling, time of execution, description, etc. All job nodes are stored in a separate system.scheduler repository. See how to manipulate it with lib-scheduler API.

Properties

Name Type Description

name

string

Name of a job, unique for the entire environment

description

string

String-format description of scheduled job

descriptor

string

Descriptor of the task to be scheduled. Format: <applicationKey>:<taskName>

config

object

JSON object contains described task parameters

calendar

object

Describes when the task should run

Properties
Name Type Description

value

string

schedule value according to its type

type

string

schedule type (CRON to be executed repeatedly at calendar positions, ONE_TIME to be executed once, or FIXED_RATE to be executed at a fixed interval)

timeZone

string

time zone of cron scheduling. It doesn’t apply to the other types.

deleteAfterRun

boolean

XP 8.1.0 optional, defaults to false. Whether a one-time job removes itself once its task has been submitted. Only applies to a one-time calendar.

user

string

Principal key of the task submitter. Format: <idProvider>:<user>

enabled

boolean

If true - the job is active and can be run according to it’s cron value and timezone.

creator

string

Principal key of user that created the task

modifier

string

Principal key of the last user that modified the task

createdTime

string

Time of the task creation

modifiedTime

string

Time of the last task modification

lastRun

string

Time of the last job run

lastTaskId

string

Task id of the last job run

Calendar

Calendar object describes when and how the task should be run. There are three possible types: one-time, cron and fixed-rate.

one-time

The task will be run only once. If the time value is passed at the moment of scheduling, then the task will be run immediately. Value format is ZULU time, documented in ISO 8601.

Example of a one-time calendar
{type: 'ONE_TIME', value: '2021-01-01T10:30:00.00Z'}

The job remains after it has run, with lastRun recording that it is done, so its name cannot be reused to run it again. XP 8.1.0 Where the name is used for a single occasion only - a publish request keyed by a uuid, say - that record protects nothing and only accumulates; deleteAfterRun makes the job remove itself once its task has been submitted.

Example of a one-time calendar that cleans up after itself
{type: 'ONE_TIME', value: '2021-01-01T10:30:00.00Z', deleteAfterRun: true}
cron

Should be used for repeatable tasks. UNIX cron lib format is expected. Also, a timezone must be specified to run the job at a particular time of the day.

Example of a cron calendar
{type: 'CRON', value: '* * * * *' // every minute
,timeZone: 'GMT+5:30'}
fixed-rate

XP 8.1.0 Should be used for repeatable tasks that belong at an interval rather than at a time of day. The value is an ISO-8601 duration, and the interval is measured from when the previous run started - not from when it finished, and not from the clock, so no timezone applies.

Example of a fixed-rate calendar
{type: 'FIXED_RATE', value: 'PT5M'} // every five minutes

What a fixed rate promises:

  • The interval is between the starts of two runs, not the gap between them.

  • A run that overruns its interval delays the next one instead of overlapping it, and the delayed run starts once its predecessor finishes.

  • Periods missed while a run overruns are not replayed, so an overrunning run shifts every later run along with it.

  • The interval is not anchored to any wall-clock position, and is not preserved across a restart or a move to another node - the next run may shift by up to one interval.

Use CRON instead where a run has to land at a particular time of day.

Configuration

There are two ways to configure custom scheduled jobs: lib API provides methods to manipulate jobs and config file is used to configure default permanent cron jobs.

System jobs

XP platform provides predefined system jobs, which can be enabled and overridden by user in config file. The config file creates jobs, it does not maintain them: XP 8.1.0 a job added to the file is created within a second, but editing an entry never updates a job that already exists, so remove or change the existing job first.

Vacuum

Deletes unused blobs and binaries from a blobstore.

Make sure you have a backup of the installation available before doing a vacuum.
Predifined vacuum job properties
init-job.vacuum.enabled=false
init-job.vacuum.cron=0 5 * * *
init-job.vacuum.descriptor=com.enonic.xp.app.system:vacuum
init-job.vacuum.description=Job to run vacuum
init-job.vacuum.user=system:su

Common vacuum process config can be found in Vacuum config file.

Audit log cleanUp

Deletes records from audit log repository.

Make sure you have a backup of the installation available before running a cleanUp.
Predefined cleanUp job properties
init-job.audit-log-cleanup.enabled=false
init-job.audit-log-cleanup.cron=0 5 * * *
init-job.audit-log-cleanup.descriptor=com.enonic.xp.app.system:audit-log-cleanup
init-job.audit-log-cleanup.description=Job to clean up old audit log history
init-job.audit-log-cleanup.user=system:su

Common cleanup process config can be found in Audit config file.

ageThreshold property must be set to appropriate value, otherwise nothing will be removed.

Distributable

A scheduled job is submitted once per due occurrence, from one node of the cluster, and the task it submits then runs on any node that has the application providing it - see task for where that can be. Which node submits is a deployment concern, set with acceptScheduling in the scheduler config file; a job behaves the same wherever it is submitted from.

XP 8.1.0 A job does not start a run while its own previous run is still going. What becomes of the run that was due depends on the calendar: a CRON occurrence is skipped, since a cron occurrence is a position in the calendar and a missed one is missed, while a FIXED_RATE run is delayed and starts once its predecessor finishes.

Not overlapping is best effort, not a guarantee. Two runs of the same job can still overlap when the cluster is partitioned, or when the record of the previous task is no longer available to be checked. A task that must never run concurrently with itself needs a lock of its own.
The guarantee is per job, not per task. Several jobs may name the same descriptor, and nothing relates them - they can run at the same time as each other.

What a scheduled task receives

A scheduled task runs with the config of its job as parameters, exactly as if it had been submitted through the task API.

XP 8.1.0 It also learns which task ran for the job last, through the schedule.lastTaskId attribute of its context. That is useful where each run continues from where the last one reached - fetching the previous run’s result to process only what has changed since. The value is absent on a job’s first run and on a job whose last run left no record.

Reading the previous run’s task id
import {get as getContext} from '/lib/xp/context';
import {get as getTask} from '/lib/xp/task';

export function run(): void {
    const lastTaskId = getContext().attributes['schedule.lastTaskId'] as string | undefined;
    const previous = lastTaskId ? getTask(lastTaskId) : null;

    if (previous) {
        log.info('Previous run: %s', previous.state);
    }
}

The chain only ever names tasks the scheduler let run, so an id that is there is one whose run actually happened.


Contents

Contents