Job

interface Job : CoroutineContext.Element

A background job. Conceptually, a job is a cancellable thing with a life-cycle that culminates in its completion.

Jobs can be arranged into parent-child hierarchies where cancellation of a parent leads to immediate cancellation of all its children recursively. Failure of a child with an exception other than CancellationException immediately cancels its parent and, consequently, all its other children. This behavior can be customized using SupervisorJob.

The most basic instances of Job interface are created like this:

  • Coroutine job is created with launch coroutine builder. It runs a specified block of code and completes on completion of this block.

  • CompletableJob is created with a Job() factory function. It is completed by calling CompletableJob.complete.

Conceptually, an execution of a job does not produce a result value. Jobs are launched solely for their side-effects. See Deferred interface for a job that produces a result.

Job states

A job has the following states:

StateisActiveisCompletedisCancelled
New (optional initial state)falsefalsefalse
Active (default initial state)truefalsefalse
Completing (transient state)truefalsefalse
Cancelling (transient state)falsefalsetrue
Cancelled (final state)falsetruetrue
Completed (final state)falsetruefalse

Usually, a job is created in the active state (it is created and started). However, coroutine builders that provide an optional start parameter create a coroutine in the new state when this parameter is set to CoroutineStart.LAZY. Such a job can be made active by invoking start or join.

A job is active while the coroutine is working or until CompletableJob is completed, or until it fails or cancelled.

Failure of an active job with an exception makes it cancelling. A job can be cancelled at any time with cancel function that forces it to transition to the cancelling state immediately. The job becomes cancelled when it finishes executing its work and all its children complete.

Completion of an active coroutine's body or a call to CompletableJob.complete transitions the job to the completing state. It waits in the completing state for all its children to complete before transitioning to the completed state. Note that completing state is purely internal to the job. For an outside observer a completing job is still active, while internally it is waiting for its children.

                                          wait children
+-----+ start +--------+ complete +-------------+ finish +-----------+
| New | -----> | Active | ---------> | Completing | -------> | Completed |
+-----+ +--------+ +-------------+ +-----------+
| cancel / fail |
| +----------------+
| |
V V
+------------+ finish +-----------+
| Cancelling | --------------------------------> | Cancelled |
+------------+ +-----------+

A Job instance in the coroutineContext represents the coroutine itself.

Cancellation cause

A coroutine job is said to complete exceptionally when its body throws an exception; a CompletableJob is completed exceptionally by calling CompletableJob.completeExceptionally. An exceptionally completed job is cancelled and the corresponding exception becomes the cancellation cause of the job.

Normal cancellation of a job is distinguished from its failure by the type of this exception that caused its cancellation. A coroutine that threw CancellationException is considered to be cancelled normally. If a cancellation cause is a different exception type, then the job is considered to have failed. When a job has failed, then its parent gets cancelled with the exception of the same type, thus ensuring transparency in delegating parts of the job to its children.

Note, that cancel function on a job only accepts CancellationException as a cancellation cause, thus calling cancel always results in a normal cancellation of a job, which does not lead to cancellation of its parent. This way, a parent can cancel its own children (cancelling all their children recursively, too) without cancelling itself.

Concurrency and synchronization

All functions on this interface and on all interfaces derived from it are thread-safe and can be safely invoked from concurrent coroutines without external synchronization.

Not stable for inheritance

Job interface and all its derived interfaces are not stable for inheritance in 3rd party libraries, as new methods might be added to this interface in the future, but is stable for use.

Types

Key
Link copied to clipboard
object Key : CoroutineContext.Key<Job>

Key for Job instance in the coroutine context.

Functions

cancel
Link copied to clipboard
abstract fun cancel(cause: CancellationException? = null)

Cancels this job with an optional cancellation cause. A cause can be used to specify an error message or to provide other details on the cancellation reason for debugging purposes. See Job documentation for full explanation of cancellation machinery.

invokeOnCompletion
Link copied to clipboard
abstract fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle

Registers handler that is synchronously invoked once on completion of this job. When the job is already complete, then the handler is immediately invoked with the job's exception or cancellation cause or null. Otherwise, the handler will be invoked once when this job is complete.

join
Link copied to clipboard
abstract suspend fun join()

Suspends the coroutine until this job is complete. This invocation resumes normally (without exception) when the job is complete for any reason and the Job of the invoking coroutine is still active. This function also starts the corresponding coroutine if the Job was still in new state.

start
Link copied to clipboard
abstract fun start(): Boolean

Starts coroutine related to this job (if any) if it was not started yet. The result is true if this invocation actually started coroutine or false if it was already started or completed.

Properties

children
Link copied to clipboard
abstract val children: Sequence<Job>

Returns a sequence of this job's children.

isActive
Link copied to clipboard
abstract val isActive: Boolean

Returns true when this job is active -- it was already started and has not completed nor was cancelled yet. The job that is waiting for its children to complete is still considered to be active if it was not cancelled nor failed.

isCancelled
Link copied to clipboard
abstract val isCancelled: Boolean

Returns true if this job was cancelled for any reason, either by explicit invocation of cancel or because it had failed or its child or parent was cancelled. In the general case, it does not imply that the job has already completed, because it may still be finishing whatever it was doing and waiting for its children to complete.

isCompleted
Link copied to clipboard
abstract val isCompleted: Boolean

Returns true when this job has completed for any reason. A job that was cancelled or failed and has finished its execution is also considered complete. Job becomes complete only after all its children complete.

onJoin
Link copied to clipboard
abstract val onJoin: SelectClause0

Clause for select expression of join suspending function that selects when the job is complete. This clause never fails, even if the job completes exceptionally.

Inheritors

CompletableJob
Link copied to clipboard
Deferred
Link copied to clipboard
NonCancellable
Link copied to clipboard

Extensions

cancel
Link copied to clipboard
fun Job.cancel(message: String, cause: Throwable? = null)

Cancels current job, including all its children with a specified diagnostic error message. A cause can be specified to provide additional details on a cancellation reason for debugging purposes.

cancelAndJoin
Link copied to clipboard
suspend fun Job.cancelAndJoin()

Cancels the job and suspends the invoking coroutine until the cancelled job is complete.

cancelChildren
Link copied to clipboard
fun Job.cancelChildren(cause: CancellationException? = null)

Cancels all children jobs of this coroutine using Job.cancel for all of them with an optional cancellation cause. Unlike Job.cancel on this job as a whole, the state of this job itself is not affected.

ensureActive
Link copied to clipboard
fun Job.ensureActive()

Ensures that current job is active. If the job is no longer active, throws CancellationException. If the job was cancelled, thrown exception contains the original cancellation cause.

Sources

common source
Link copied to clipboard