public Job
A background job. Conceptually, a job is a cancellable thing with a simple life-cycle that
culminates in its completion. Jobs can be arranged into parent-child hierarchies where cancellation
or completion of parent immediately cancels all its Job.getChildren
.
The most basic instances of interface Job
are created with launch coroutine builder or with a
Job()
factory function. Other coroutine builders and primitives like
interface Deferred
also implement interface Job
interface.
A job has the following states:
| State | Job.isActive
| Job.isCompleted
| Job.isCancelled
|
| --------------------------------------- | ---------- | ------------- | ------------- |
| New (optional initial state) | false
| false
| false
|
| Active (default initial state) | true
| false
| false
|
| Completing (optional transient state) | true
| false
| false
|
| Cancelling (optional transient state) | false
| false
| true
|
| Cancelled (final state) | false
| true
| true
|
| Completed (final state) | false
| true
| false
|
Usually, a job is created in active state (it is created and started). However, coroutine builders
that provide an optional start
parameter create a coroutine in new state when this parameter is set to
CoroutineStart.LAZY. Such a job can be made active by invoking Job.start
or Job.join
.
A job can be cancelled at any time with Job.cancel
function that forces it to transition to
cancelling state immediately. Job that is not backed by a coroutine (see Job()
function) and does not have
Job.getChildren
becomes cancelled on Job.cancel
immediately.
Otherwise, job becomes cancelled when it finishes executing its code and
when all its children Job.isCompleted
.
wait children
+-----+ start +--------+ complete +-------------+ finish +-----------+
| New | ---------------> | Active | -----------> | Completing | -------> | Completed |
+-----+ +--------+ +-------------+ +-----------+
| | |
| cancel | cancel | cancel
V V |
+-----------+ finish +------------+ |
| Cancelled | <--------- | Cancelling | <----------------+
|(completed)| +------------+
+-----------+
A job in the CoroutineScope.getCoroutineContext
represents the coroutine itself.
A job is active while the coroutine is working and job's cancellation aborts the coroutine when
the coroutine is suspended on a cancellable suspension point by throwing CancellationException.
A job can have a parent job. A job with a parent is cancelled when its parent is cancelled or completes exceptionally. Parent job waits for all its children to complete in completing or cancelling state. 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.
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.
Modifier and Type | Interface and Description |
---|---|
static class |
Job.DefaultImpls
A background job. Conceptually, a job is a cancellable thing with a simple life-cycle that
culminates in its completion. Jobs can be arranged into parent-child hierarchies where cancellation
or completion of parent immediately cancels all its
Job.getChildren . |
static class |
Job.Key
Key for
interface Job instance in the coroutine context. |
Modifier and Type | Field and Description |
---|---|
static Job.Key |
Key
Key for
interface Job instance in the coroutine context. |
Modifier and Type | Method and Description |
---|---|
boolean |
cancel(java.lang.Throwable cause)
Cancels this job with an optional cancellation cause. The result is
true if this job was
cancelled as a result of this invocation and false otherwise
(if it was already completed or if it is class NonCancellable ).
Repeated invocations of this function have no effect and always produce false . |
java.util.concurrent.CancellationException |
getCancellationException()
Returns CancellationException that signals the completion of this job. This function is
used by cancellable suspending functions. They throw exception
returned by this function when they suspend in the context of this job and this job becomes complete.
|
kotlin.sequences.Sequence<kotlinx.coroutines.experimental.Job> |
getChildren()
Returns a sequence of this job's children.
|
SelectClause0 |
getOnJoin()
Clause for select expression of
Job.join suspending function that selects when the job is complete.
This clause never fails, even if the job completes exceptionally. |
DisposableHandle |
invokeOnCompletion(kotlin.jvm.functions.Function1<? super java.lang.Throwable,kotlin.Unit> handler)
Registers handler that is synchronously invoked once on completion of this job.
When job is already complete, then the handler is immediately invoked
with a job's exception or cancellation cause or
null . Otherwise, handler will be invoked once when this
job is complete. |
DisposableHandle |
invokeOnCompletion(boolean onCancelling,
boolean invokeImmediately,
kotlin.jvm.functions.Function1<? super java.lang.Throwable,kotlin.Unit> handler)
Registers handler that is synchronously invoked once on cancellation or completion of this job.
When job is already cancelling or complete, then the handler is immediately invoked
with a job's cancellation cause or
null unless invokeImmediately is set to false.
Otherwise, handler will be invoked once when this job is cancelled or complete. |
boolean |
isActive()
Returns
true when this job is active -- it was already started and has not completed or cancelled yet.
The job that is waiting for its Job.getChildren to complete is still considered to be active if it
was not cancelled. |
boolean |
isCancelled()
Returns
true if this job was Job.cancel . In the general case, it does not imply that the
job has already Job.isCompleted (it may still be cancelling whatever it was doing). |
boolean |
isCompleted()
Returns
true when this job has completed for any reason. A job that was cancelled and has
finished its execution is also considered complete. Job becomes complete only after
all its Job.getChildren complete. |
java.lang.Object |
join(kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p)
Suspends coroutine until this job is complete. This invocation resumes normally (without exception)
when the job is complete for any reason and the
interface Job of the invoking coroutine is still Job.isActive .
This function also Job.start the corresponding coroutine if the interface Job was still in new state. |
boolean |
start()
Starts coroutine related to this job (if any) if it was not started yet.
The result
true if this invocation actually started coroutine or false
if it was already started or completed. |
static Job.Key Key
Key for interface Job
instance in the coroutine context.
interface Job
boolean isActive()
Returns true
when this job is active -- it was already started and has not completed or cancelled yet.
The job that is waiting for its Job.getChildren
to complete is still considered to be active if it
was not cancelled.
Job.getChildren
boolean isCompleted()
Returns true
when this job has completed for any reason. A job that was cancelled and has
finished its execution is also considered complete. Job becomes complete only after
all its Job.getChildren
complete.
Job.getChildren
boolean isCancelled()
Returns true
if this job was Job.cancel
. In the general case, it does not imply that the
job has already Job.isCompleted
(it may still be cancelling whatever it was doing).
Job.cancel
,
Job.isCompleted
java.util.concurrent.CancellationException getCancellationException()
Returns CancellationException that signals the completion of this job. This function is used by cancellable suspending functions. They throw exception returned by this function when they suspend in the context of this job and this job becomes complete.
This function returns the original Job.cancel
cause of this job if that cause
was an instance of
CancellationException. Otherwise (if this job was cancelled with a cause of a different type, or
was cancelled without a cause, or had completed normally), an instance of exception JobCancellationException
is
returned. The JobCancellationException.cause of the resulting exception JobCancellationException
references
the original cancellation cause that was passed to Job.cancel
function.
This function throws IllegalStateException when invoked on a job that has not
Job.isCompleted
nor Job.isCancelled
yet.
boolean start()
Starts coroutine related to this job (if any) if it was not started yet.
The result true
if this invocation actually started coroutine or false
if it was already started or completed.
boolean cancel(java.lang.Throwable cause)
Cancels this job with an optional cancellation cause. The result is true
if this job was
cancelled as a result of this invocation and false
otherwise
(if it was already completed or if it is class NonCancellable
).
Repeated invocations of this function have no effect and always produce false
.
When cancellation has a clear reason in the code, an instance of CancellationException should be created at the corresponding original cancellation site and passed into this method to aid in debugging by providing both the context of cancellation and text description of the reason.
class NonCancellable
kotlin.sequences.Sequence<kotlinx.coroutines.experimental.Job> getChildren()
Returns a sequence of this job's children.
A job becomes a child of this job when it is constructed with this job in its
CoroutineContext or using an explicit parent
parameter.
A parent-child relation has the following effect:
Cancellation of parent with Job.cancel
or its exceptional completion (failure)
immediately cancels all its children.
Parent cannot complete until all its children are complete. Parent waits for all its children to complete in completing or cancelling state.
Uncaught exception in a child, by default, cancels parent. In particular, this applies to children created with launch coroutine builder. Note, that async and other future-like coroutine builders do not have uncaught exceptions by definition, since all their exceptions are caught and are encapsulated in their result.
Job.cancel
java.lang.Object join(kotlin.coroutines.experimental.Continuation<? super kotlin.Unit> p)
Suspends coroutine until this job is complete. This invocation resumes normally (without exception)
when the job is complete for any reason and the interface Job
of the invoking coroutine is still Job.isActive
.
This function also Job.start
the corresponding coroutine if the interface Job
was still in new state.
Note, that the job becomes complete only when all its children are complete.
This suspending function is cancellable and always checks for the cancellation of invoking coroutine's Job.
If the interface Job
of the invoking coroutine is cancelled or completed when this
suspending function is invoked or while it is suspended, this function
throws CancellationException.
In particular, it means that a parent coroutine invoking join
on a child coroutine that was started using
launch(coroutineContext) { ... }
builder throws CancellationException if the child
had crashed, unless a non-standard interface CoroutineExceptionHandler
if installed in the context.
This function can be used in select invocation with Job.getOnJoin
clause.
Use Job.isCompleted
to check for completion of this job without waiting.
There is cancelAndJoin function that combines an invocation of Job.cancel
and join
.
SelectClause0 getOnJoin()
Clause for select expression of Job.join
suspending function that selects when the job is complete.
This clause never fails, even if the job completes exceptionally.
Job.join
DisposableHandle invokeOnCompletion(kotlin.jvm.functions.Function1<? super java.lang.Throwable,kotlin.Unit> handler)
Registers handler that is synchronously invoked once on completion of this job.
When job is already complete, then the handler is immediately invoked
with a job's exception or cancellation cause or null
. Otherwise, handler will be invoked once when this
job is complete.
The resulting interface DisposableHandle
can be used to DisposableHandle.dispose
the
registration of this handler and release its memory if its invocation is no longer needed.
There is no need to dispose the handler after completion of this job. The references to
all the handlers are released when this job completes.
Installed handler should not throw any exceptions. If it does, they will get caught,
wrapped into exception CompletionHandlerException
, and rethrown, potentially causing crash of unrelated code.
Note: Implementations of CompletionHandler
must be fast and lock-free.
DisposableHandle invokeOnCompletion(boolean onCancelling, boolean invokeImmediately, kotlin.jvm.functions.Function1<? super java.lang.Throwable,kotlin.Unit> handler)
Registers handler that is synchronously invoked once on cancellation or completion of this job.
When job is already cancelling or complete, then the handler is immediately invoked
with a job's cancellation cause or null
unless invokeImmediately is set to false.
Otherwise, handler will be invoked once when this job is cancelled or complete.
Invocation of this handler on a transition to a transient cancelling state
is controlled by onCancelling boolean parameter.
The handler is invoked on invocation of Job.cancel
when
job becomes cancelling if onCancelling parameter is set to true
. However,
when this interface Job
is not backed by a coroutine, like interface CompletableDeferred
or interface CancellableContinuation
(both of which do not posses a cancelling state), then the value of onCancelling parameter is ignored.
The resulting interface DisposableHandle
can be used to DisposableHandle.dispose
the
registration of this handler and release its memory if its invocation is no longer needed.
There is no need to dispose the handler after completion of this job. The references to
all the handlers are released when this job completes.
Installed handler should not throw any exceptions. If it does, they will get caught,
wrapped into exception CompletionHandlerException
, and rethrown, potentially causing crash of unrelated code.
Note: This function is a part of internal machinery that supports parent-child hierarchies
and allows for implementation of suspending functions that wait on the Job's state.
This function should not be used in general application code.
Implementations of CompletionHandler
must be fast and lock-free.
onCancelling
- when true
, then the handler is invoked as soon as this job transitions to cancelling state;
when false
then the handler is invoked only when it transitions to completed state.invokeImmediately
- when true
and this job is already in the desired state (depending on onCancelling),
then the handler is immediately and synchronously invoked and class NonDisposableHandle
is returned;
when false
then class NonDisposableHandle
is returned, but the handler is not invoked.handler
- the handler.Job.cancel
,
interface Job
,
interface CompletableDeferred
,
interface CancellableContinuation
,
interface DisposableHandle
,
DisposableHandle.dispose
,
exception CompletionHandlerException