Main Page » XQuery » Functions » Job Functions

Job Functions

This module provides functions for registering new query jobs and orchestrating existing jobs. Jobs can be queries, commands, operations performed by a database client, and HTTP requests.

If you want to evaluate queries as part of the same query, the XQuery Functions are usually the better choice.

Conventions

All functions are in the http://basex.org/modules/job namespace, to which the job prefix is statically bound. Errors will be bound to the same prefix.

Synchronous Execution

job:execute

Updated: Raise deadlock error if execution would deadlock the calling query.

Updated: A function item can be invoked instead of a query.

Signature
job:execute(  $query     as (xs:string|xs:anyURI|fn(*)),  $bindings  as (map((xs:string|xs:QName), item()*)|array(*))?  := {}) as item()*admin
SummaryRegisters a job for the specified $query (of type xs:string, or of type xs:anyURI if it points to a resource), waits for its execution and returns its result or a raised error. The query can be updating, and variables and the context value can be declared via $bindings (see xquery:eval for more details).

Instead of a query, a function item can be supplied, which is invoked with the arguments of the $bindings array.

The function is helpful for scripting. It can be used to run multiple XQuery expressions one after another.

Deadlocks: A deadlock error is raised if the registered query requires database locks that the calling query holds: the registered query cannot start before the calling query completes, while the calling query waits infinitely for its result. This happens, for example, if the registered query updates a database that the calling query has already locked. Instead of blocking, the call fails with an error that reports the locks required by the registered job.

It is safe to use the function if the calling query does not lock the databases addressed by the registered query. See Transaction Management for further details.

Updating function items: An updating function item always raises this error. The locks of a function item are known to the calling query, which therefore write-locks the databases the job will update before the job is registered. Supply an updating query as string instead.

Errors
deadlockExecution of the job would deadlock the calling query.
Examples
job:execute('db:create("test")'),
job:execute('db:put-value("test", 1 to 10, "numbers")')
Creates a database and adds an XQuery value to the database.
for $n in 1 to 8
let $script := xs:anyURI('script' || $n || '.xq')
return try {
  job:execute($script, { 'n': $n })
} catch * {
  '* ' || $script || ': ' || $err:description
}
Executes eight scripts in a row and binds the script number to a variable. Reports back errors.

Asynchronous Execution

There are cases in which a client does not, or cannot, wait until a request is fully processed. The client may be a browser, which sends an HTTP request to the server to start another time-consuming query job. The functions in this section allow you to register new query jobs and access existing ones. Jobs may be executed immediately (i.e., as soon as a free slot is available) or scheduled for repeated execution. Each registered job gets a job ID, and the ID can be used to retrieve a query result, stop a job, or wait for its termination.

job:eval

Updated: Support for Cron syntax and daylight saving changes added.

Updated: Options added for permissions, timeouts and memory limits.

Updated: A function item can be invoked instead of a query.

Signature
job:eval(  $query     as (xs:string|xs:anyURI|fn(*)),  $bindings  as (map((xs:string|xs:QName), item()*)|array(*))?  := {},  $options   as map(*)?  := {}) as xs:stringadmin
SummarySchedules the evaluation of a new query job for the supplied $query (of type xs:string, or of type xs:anyURI if it points to a resource), and returns a job ID. The job will be queued until a free slot is available, and the query result can be cached. The query can be updating, and variables and the context value can be declared via $bindings (see xquery:eval for more details).

Instead of a query, a function item can be supplied, which is invoked with the arguments of the $bindings array. A function item can neither be registered as service, because services are written to disk, nor be scheduled with start, interval or cron, because a scheduled job outlives the query that created it.

The following $options are available:
optiondefaultdescription
cachefalse() The result is cached in main memory until it is fetched via job:result, or until CACHETIMEOUT is exceeded. If the query raises an error, it will be cached and returned instead.
permission The job will be evaluated with the specified permissions (see User Management). Permissions cannot be escalated: an error is raised if the current user does not have them.
timeout The job will be stopped after the specified number of seconds.
memory The job will be stopped if the specified number of megabytes is exceeded. The check is based on the total heap usage of the server: if the limit is exceeded, garbage collection is enforced, and the job that has allocated most memory since it was started will be stopped. The option requires GC to be enabled in your JVM.
servicefalse() Additionally register the job as service. Registered services are written to disk, they must have no variable bindings, and they must be assigned an id, which is the handle for unregistering them. The memory, timeout and permission options are rejected: runtime restrictions belong to the session that starts a job, not to a job definition that outlives it.
logfalse() Write the specified string to the database logs. Two log entries are stored, one at the beginning and another one after the execution of the job.
start An xs:dayTimeDuration, xs:time, xs:dateTime or xs:integer value can be specified to delay the execution of the query:
  • If xs:dayTimeDuration is specified, the query will be queued after the specified duration has passed. Examples of valid values are: P1D (1 day), PT5M (5 minutes), PT0.1S (100 ms). An error will be raised if a negative value is specified.
  • If xs:dateTime is specified, the query will be executed at this date. Examples of valid values are: 2018-12-31T23:59:59 (New Year’s Eve 2018, close to midnight). An error will be raised if the specified time lies in the past.
  • If xs:time is specified, the query will be executed at this time of the day. Examples of valid times are: 02:00:00 (2am local time), 12:00:00Z (noon, UTC). If the time lies in the past, the query will be executed the next day.
  • An integer will be interpreted as minutes. If the specified number is smaller than the elapsed minutes of the current hour, the query will be executed one hour later.
interval An xs:dayTimeDuration value can be specified to execute the query periodically. An error is raised if the specified interval is less than one second (PT1S). If the next scheduled call is due, and if a query with the same ID is still running, it will be skipped.

If start denotes a time in the past, it serves as an anchor: the first execution will be the first repetition that lies in the future. A job with start set to 2020-01-01T00:00:30 and interval set to PT1M will be executed every minute, 30 seconds past the minute.

Scheduling is aligned to the local wall clock: a job scheduled for a particular time of day keeps that time across daylight saving changes (a daily job set to 02:00:00 is not shifted to 01:00:00 or 03:00:00 by a time switch).

cron A cron expression can be specified to execute the query at recurring points in time that cannot be expressed as a fixed interval, such as 0 8 * * MON-FRI (every weekday at 8am). The option is mutually exclusive with start and interval.
end Scheduling can be stopped after a given time or duration. The string format is the same as for start. An error is raised if the resulting end time is earlier than the start time.
base-uri The base-uri property for the query. This URI will be used when resolving relative URIs, such as with fn:doc.
id A custom job ID. The ID must not have the format of a generated ID (the job prefix, followed by a number), and it can only be assigned if no job with the same ID exists.
Errors
cronThe specified cron expression is invalid, or it will never match a date.
functionA function item cannot be registered as service or scheduled for later execution.
idThe specified ID is invalid or has already been assigned.
optionsThe specified options are conflicting.
overflowToo many queries are registered, or too many query results are cached.
permissionThe current user does not have the permissions requested for the job.
rangeA specified time or duration is out of range.
Examples
job:eval("1 + 3", (), { 'cache': true() })
Cache query result. The returned ID can be used to pick up the result with job:result.
job:eval(fn($name) { 'Hello ' || $name }, [ 'World' ], { 'cache': true() })
Invokes a function item with a single argument.
job:eval(
  "import module namespace mail='mail'; mail:send('Happy birthday!')",
  (),
  { 'start': '2018-09-01T06:00:00' }
)
A happy birthday mail will be sent at the given date.
declare
  %rest:POST("{$query}")
  %rest:path('/start-scheduling')
function local:start($query) {
  job:eval($query, (), { 'start': '02:00:00', 'interval': 'P1D' })
};

declare
  %rest:path('/stop-scheduling/{$id}')
function local:stop($id) {
  job:remove($id)
};
The RESTXQ functions can be called to execute a query at 02:00 daily. An ID will be returned by the first function, which can be used to stop the scheduler via the second function.
job:eval(xs:anyURI('report.xq'), (), { 'cron': '0 6 * * MON-FRI' })
The query will be evaluated at 6am on every weekday. See Cron Syntax for the supported patterns.
job:eval("prof:sleep(1500)", (), { 'interval': 'PT1S', 'end': 'PT10S' })
Query execution is scheduled for every second, and for 10 seconds in total. As the query itself will take 1.5 seconds, it will only be executed every second time.
job:eval(xs:anyURI('cleanup.xq'))
The query in the specified file will be evaluated once.
job:eval(static-base-uri(), options := { 'start': 'PT5S' })
The following expression, if stored in a file, will be evaluated every 5 seconds.

job:result

Signature
job:result(  $id       as xs:string,  $options  as map(*)?  := {}) as item()*admin
SummaryReturns the cached result of a job with the specified job $id:
  • If the original job has raised an error, the cached error will be raised instead.
  • The cached result or error will be dropped after it has been retrieved.
  • If the result has not been cached or if it has been dropped, an empty sequence is returned.

The following $options are available:

optiondefaultdescription
keepfalse() Keep the cached result or error after retrieval.
Examples
declare
  %rest:path('/result/{$id}')
function local:result($id) {
  job:result($id)
};
The following RESTXQ function will either return the result of a previously started job or raise an error.

job:remove

Signature
job:remove(  $id       as xs:string,  $options  as map(*)?  := {}) as empty-sequence()admin
SummaryTriggers the cancelation of a job with the specified $id, cancels a scheduled job or removes a cached result. Unknown IDs are ignored. All jobs are gracefully stopped; it is up to the process to decide when it is safe to shut down. The following $options are available:
optiondefaultdescription
servicefalse() Additionally remove the job from the job services list.
Examples
job:list()[. != job:current()] ! job:remove(.)
Stops and discards all jobs except for the current one.
job:remove(job:current())
Interrupts the current job.

job:wait

Signature
job:wait(  $id  as xs:string) as empty-sequence()admin
SummaryWaits for the completion of a job with the specified $id:
  • The function will terminate immediately if the job ID is unknown. This is the case if a future job has not been queued yet, or if the ID has already been discarded after job evaluation.
  • If the function is called with the ID of a queued job, or of a repeatedly executed job, it may stall and never terminate.
Errors
selfThe current job cannot be addressed.

Services

A job can be registered as service by supplying the service option to job:eval:

(: register job as service; will be run every day at 1 am :)
job:eval(
  'db:drop("tmp")',
  options := { 'id':'cleanup', 'start':'01:00:00', 'interval':'P1D', 'service': true() }
),

(: list registered services :)
job:services(),
(: result: <job base-uri="..." id="cleanup" interval="P1D" start="01:00:00">db:drop("tmp")</job> :)

(: unregister job :)
job:remove('cleanup', { 'service': true() })
Notes:
  • All job services will be scheduled for evaluation when the BaseX server or BaseX HTTP server is started.
  • If a job service is outdated (e.g. because a supplied end time has been exceeded), it will be removed from the jobs file at startup time.
  • The job definitions are stored in a jobs.xml file in the database directory. It can also be edited manually.
  • Each service requires an id, and no two services may share one: the ID is the handle for unregistering a service. Entries of older versions that have no ID are still evaluated, but they can only be removed from the jobs file manually.
  • Only the options that were supplied are stored; the remaining ones are reapplied with their default values when the file is read.

View Jobs

job:current

Signature
job:current() as xs:string
SummaryReturns the ID of the current job.

job:list

Signature
job:list() as xs:string*admin
SummaryReturns the IDs of all jobs that are currently registered. The list includes scheduled, queued, running, stopped, and finished jobs with cached results.
Examples
job:list()
Returns the same job ID as job:current if no other job is registered.

job:list-details

Signature
job:list-details(  $id  as xs:string  := ()) as element(job)*admin
SummaryReturns information on all jobs that are currently registered, or on a job with the specified $id (or an empty sequence if this job is not found). The list includes scheduled, queued, running jobs, and cached jobs. A string representation of the job, or its URI, will be returned as a value. The returned elements have additional attributes:
  • id: job ID
  • type: type of the job (command, query, REST, RESTXQ, etc.)
  • state: current state of the job: scheduled, queued, running, cached
  • user: user who started the job
  • duration: evaluation time (included if a job is running or if the result was cached)
  • start: next start of job (included if a job will be executed repeatedly)
  • interval, cron: repetition of the job (included if the corresponding option was supplied)
  • time: time when job was registered
  • read: read locks ((global): global locking, (none): no locking)
  • write: write locks ((global): global locking, (none): no locking)

job:next

Added: New function.

Signature
job:next(  $cron   as xs:string,  $count  as xs:integer  := 1) as xs:dateTime*
SummaryReturns the next $count points in time at which the cron expression $cron will be triggered. No job is registered, and no query is evaluated: the function only reports when a job with this expression would be run.

Fewer than $count values are returned if the expression stops matching; the result is empty if it will never match again.

The results are relative to fn:current-dateTime, and are therefore stable: repeated calls within a single query return the same points in time.

Errors
cronThe specified cron expression is invalid, or it will never match a date.
rangeA specified time or duration is out of range.
Examples
job:next('0 8 * * MON-FRI', 3)
Returns the next three weekday mornings, e.g. 2026-07-23T08:00:00+02:00, 2026-07-24T08:00:00+02:00, 2026-07-27T08:00:00+02:00. The weekend is skipped.
job:next('0 0 30 2 *')
Returns an empty sequence: February 30 does not exist.

job:bindings

Signature
job:bindings(  $id  as xs:string) as map(*)admin
SummaryReturns the variable bindings of an existing job with the specified $id. If a function item is invoked, its arguments are returned, using the parameter names of the function. If no variables have been bound to this job, an empty map is returned.

job:finished

Signature
job:finished(  $id  as xs:string) as xs:booleanadmin
SummaryIndicates if the evaluation of an already running job with the specified $id has finished. As the IDs of finished jobs will usually be discarded, unless caching is enabled, the function will also return true for unknown jobs.
  • false indicates that the job is queued or currently running.
  • true will be returned if the job has finished, if it is scheduled for a later time or waiting for its next repetition, or if the ID is unknown (because the IDs of all finished jobs will not be cached).

job:services

Signature
job:services() as element(job)*admin
SummaryReturns a list of all jobs that have been persistently registered as Services.
Errors
serviceA service has no ID, the ID is already assigned to another service, an option is not allowed for services, or registered services cannot be parsed, added or removed.

Errors

CodeDescription
cronThe specified cron expression is invalid, or it will never match a date.
deadlockExecution of the job would deadlock the calling query.
functionA function item cannot be registered as service or scheduled for later execution.
idThe specified ID is invalid or has already been assigned.
optionsThe specified options are conflicting.
overflowToo many queries are registered, or too many query results are cached.
permissionThe current user does not have the permissions requested for the job.
rangeA specified time or duration is out of range.
selfThe current job cannot be addressed.
serviceA service has no ID, the ID is already assigned to another service, an option is not allowed for services, or registered services cannot be parsed, added or removed.

Changelog

Version 13.0
  • Added: job:next
  • Updated: job:eval: a service must have a unique id; memory, timeout and permission are rejected.
  • Updated: job:eval, job:list-details: Cron syntax added.
  • Updated: job:eval: permission, timeout and memory options added.
  • Updated: job:eval: Support for daylight saving changes.
  • Updated: job:execute: Raise deadlock error if execution would deadlock the calling query.
  • Updated: job:eval, job:execute: a function item can be invoked instead of a query.
Version 12.0Version 10.0
  • Added: job:bindings
  • Updated: Renamed from Jobs Module to Job Module. The namespace URI has been updated as well.
  • Updated: job:remove renamed from jobs:stop.
  • Updated: job:result: options argument added.
Version 9.7
  • Updated: job:result: return empty sequence if no result is cached.
Version 9.5
  • Updated: job:eval: integers added as valid start and end times.
Version 9.4Version 9.2
  • Removed: job:invoke (merged with job:eval)
Version 9.1Version 9.0Version 8.6Version 8.5
  • Added: New module added.

⚡Generated with XQuery