Technical reference
The Job plugin provides a small set of base classes for building an asynchronous job execution pipeline: a Job to hold the work and its audit trail, a JobStatus enum to represent where that work stands, a JobRunner to hold configuration and do the work, and a JobExecutionTask to find pending jobs and run them on a schedule.
Dependencies
| Dependency | Description |
|---|---|
com.psddev:cms-db | Provides Content and the ToolUi annotations used to control how a job appears in the CMS tool. |
com.psddev:dari-db | Provides Record, Query, and Modification, which Job and its supporting classes build on. |
com.psddev:dari-util | Provides Task and RepeatingTask, which JobExecutionTask extends. |
joda-time | Used by JobExecutionTask to calculate its run schedule. |
Installation
- Maven
- Gradle
- Gradle (Kotlin DSL)
<!-- Requires Brightspot 4.5 or later. -->
<dependency>
<groupId>com.brightspot.job</groupId>
<artifactId>job</artifactId>
<version>1.0.2</version>
</dependency>
// Requires Brightspot 4.5 or later.
implementation 'com.brightspot.job:job:1.0.2'
// Requires Brightspot 4.5 or later.
implementation("com.brightspot.job:job:1.0.2")
API reference
JobStatus
Interface that a job's status enum implements. Each enum value maps to a StatusProperty that tells the job execution system how to treat jobs in that status—whether they are still pending, should be retried, are polling for an external result, or have reached a terminal state.
| Member | Description |
|---|---|
JobStatus#getProperty() | Returns the StatusProperty for this status. Required. More than one status can share the same property. |
JobStatus.StatusProperty | Enum of PRIORITY, PENDING, RETRY, POLLING, SUCCESS, PERMANENT_FAILURE, MAX_RETRIES. |
JobStatus#isPending(), #isPriority(), #isRetriesAllowed(), #isPolling(), #isMaxRetriesExceeded(), #isPermanentFailure() | Convenience checks against the corresponding StatusProperty. |
JobStatus#isSuccessfulCompletion() | True for SUCCESS statuses. |
JobStatus#isUnsuccessfulCompletion() | True for PERMANENT_FAILURE or MAX_RETRIES statuses. |
JobStatus.values(Class) | Static helper that returns all enum constants of a JobStatus class, regardless of property. |
JobStatus.priorityStatuses(Class), #pendingStatuses(Class), #retryStatuses(Class), #pollingStatuses(Class), #maxRetriesStatuses(Class) | Static helpers that return the enum constants of a JobStatus class matching the corresponding StatusProperty. |
JobStatus.find(Class, String) | Static helper that looks up a status by its enum name. |
Job
Abstract Record representing a single queued unit of work, its current status, and its activity log. Extend this class for each distinct kind of job in your application.
Must implement:
| Method | Description |
|---|---|
Job#getStatus() | Returns the status of the most recent execution. |
Job#setStatus(S) | Sets the status of the most recent execution. |
Provided:
| Method | Description |
|---|---|
Job#getQueueDate() | The date the job was queued. Set automatically on first save. |
Job#getLastActivityDate() | The date of the most recent status change. |
Job#getCompletionStatus() | SUCCESS or FAILURE once the job reaches a terminal state, null otherwise. Calculated automatically from #getStatus() on save. |
Job#getLog() | The ordered list of JobActivity entries recorded for this job. |
Job#getAttempts() | The number of execution attempts logged so far. |
Job#getRetries(Class) | The number of consecutive retry-eligible attempts since the last non-retry status. |
Job#getSecondsInQueue() | Seconds between the queue date and the last activity date. |
Job#getRunner() / #setRunner(JobRunner) | The JobRunner responsible for executing this job. |
Job#logActivity(JobExecutionResult, Consumer<String>) | Records the result of an execution, updates the job's status and last activity date, and invokes the supplied logger. Adds a new JobActivity entry to #getLog(), unless the result repeats the same polling status and message as the previous entry, in which case it increments a polling counter instead of adding a duplicate entry. Called by JobExecutionTask; not typically called directly from a JobRunner. |
Job#afterLogActivity(JobExecutionResult, Consumer<String>) | Override to run custom logic immediately after an activity is logged. No-op by default. |
Job#calculateCompletionStatus() | Derives SUCCESS, FAILURE, or null from the current status's isSuccessfulCompletion() / isUnsuccessfulCompletion(). |
JobRunner
Interface for the object that holds configuration for a group of jobs and does the actual work. JobRunner implementations are Records saved in the database so JobExecutionTask can find and enable or disable them without a deploy.
| Method | Description |
|---|---|
JobRunner#execute(Job, Task) | Does the job. parentTask is the JobExecutionTask supervising the execution. Return the resulting status and a message; the task applies the status to the job. |
JobRunner#isEnabled() | Return false to skip this runner entirely. |
JobRunner#getTaskHostOrIpAddress() | The hostname or IP address jobs for this runner are allowed to run on. Must resolve to the current host's IP address for the runner to execute; if null, or if it does not resolve to the current host, the runner is skipped on every execution cycle. |
JobRunner#getMaxNumberOfRetries() | Maximum retry attempts for statuses with a RETRY property. |
JobRunner#getMinSecondsBetweenRetries() | Minimum delay between retry attempts. |
JobRunner#getMinSecondsBetweenPolls() | Minimum delay between polling attempts. |
JobRunner#getParallelLevel() | Number of jobs to execute concurrently for this runner. Defaults to 1. |
JobRunner#handleException(Job, Throwable) | Return a JobExecutionResult if #execute throws. |
JobExecutionResult
The status and message returned from JobRunner#execute(Job, Task) or #handleException(Job, Throwable). JobExecutionTask applies this result to the job by calling Job#logActivity(JobExecutionResult, Consumer).
| Constructor | Description |
|---|---|
JobExecutionResult(S status, String message) | Creates a result with the given status and message. |
JobExecutionResult(S status, String message, Throwable exception) | Creates a result with the given status, and appends the exception's stack trace to the message. |
JobExecutionTask
Abstract RepeatingTask that queries for pending jobs and executes them using their configured JobRunners, in priority, pending, retry, then polling order.
Provided:
| Method | Description |
|---|---|
JobExecutionTask#jobClass() | The Job subclass to query for. Resolved automatically from the subclass's generic type parameter; override only if that parameter is not a concrete class. |
JobExecutionTask#jobRunnerClass() | The JobRunner subclass to query for. Resolved automatically the same way as #jobClass(). Can be an abstract class shared by multiple runner implementations, in which case all matching jobs run through the same task. |
JobExecutionTask#statusClass() | The JobStatus enum used to determine which statuses are pending, retryable, and so on. Resolved automatically the same way as #jobClass(). |
Configuration
Override the following methods on a JobExecutionTask subclass to change how often and how many jobs it processes:
| Method | Default | Description |
|---|---|---|
JobExecutionTask#getRunEverySeconds() | 3 | How often the task checks for jobs to run. |
JobExecutionTask#getBatchSize() | 10 | Number of pending, retry, or polling jobs fetched per runner on each run. |
JobExecutionTask#getPriorityBatchSize() | 10 | Number of priority jobs fetched per runner on each run. |
JobExecutionTask#getEnabledRunnersCacheSeconds() | 15 | How long the list of enabled job runners is cached before being requeried. |
Override JobRunner#getParallelLevel(), #getMaxNumberOfRetries(), #getMinSecondsBetweenRetries(), and #getMinSecondsBetweenPolls() to control concurrency and retry timing per runner, since JobRunner instances are database records that can be reconfigured without a deploy.