public Job
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 parent lead to an immediate cancellation of all its Job.getChildren
. Failure or cancellation of a child
with an exception other than CancellationException immediately cancels its parent. This way, parent
can Job.cancel
its own children (including all their children recursively) without cancelling itself.
The most basic instances of interface Job
are created with BuildersKt.launch
coroutine builder or with a
Job()
factory function. By default, a failure of any of the job's children leads to an immediately failure
of its parent and cancellation of the rest of its children. This behavior can be customized using SupervisorKt.SupervisorJob
.
Conceptually, an execution of the job does not produce a result value. Jobs are launched solely for their
side-effects. See interface Deferred
interface for a job that produces a result.
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 (transient state) | true
| false
| false
|
| Cancelling (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 is active while the coroutine is working. Failure of the job with exception makes it cancelling.
A job can be cancelled it at any time with Job.cancel
function that forces it to transition to
cancelling state immediately. The job becomes cancelled when it finishes executing it work.
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.
A job can have a parent job. A job with a parent is cancelled when its parent is cancelled. Parent job waits in completing or cancelling state for all its children to complete before finishing. 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.
Normal cancellation of a job is distinguished from its failure by the type of its cancellation exception cause.
If the cause of cancellation is CancellationException, then the job is considered to be cancelled normally.
This usually happens when Job.cancel
is invoked without additional parameters. If the cause of cancellation is
a different exception, then the job is considered to have failed. This usually happens when the code of the job
encounters some problem and throws an exception.
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 life-cycle that
culminates in its completion.
|
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 |
---|---|
void |
cancel()
Cancels this job.
See
interface Job documentation for full explanation of cancellation machinery. |
kotlin.sequences.Sequence<kotlinx.coroutines.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. |
boolean |
isActive()
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 Job.getChildren to complete is still considered to be active if it
was not cancelled nor failed. |
boolean |
isCancelled()
Returns
true if this job was cancelled for any reason, either by explicit invocation of Job.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 Job.isCompleted , because it may still be finishing whatever it was doing and
waiting for its Job.getChildren to complete. |
boolean |
isCompleted()
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 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 nor was cancelled yet.
The job that is waiting for its Job.getChildren
to complete is still considered to be active if it
was not cancelled nor failed.
See interface Job
documentation for more details on job states.
Job.getChildren
,
interface Job
boolean isCompleted()
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 Job.getChildren
complete.
See interface Job
documentation for more details on job states.
Job.getChildren
,
interface Job
boolean isCancelled()
Returns true
if this job was cancelled for any reason, either by explicit invocation of Job.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 Job.isCompleted
, because it may still be finishing whatever it was doing and
waiting for its Job.getChildren
to complete.
See interface Job
documentation for more details on cancellation and failures.
Job.cancel
,
Job.isCompleted
,
Job.getChildren
,
interface Job
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.
void cancel()
Cancels this job.
See interface Job
documentation for full explanation of cancellation machinery.
interface Job
kotlin.sequences.Sequence<kotlinx.coroutines.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 BuildersKt.launch
coroutine builder. Note, that
BuildersKt.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
,
BuildersKt.launch
,
BuildersKt.async
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 JobKt.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 meaning of cause
that is passed to the handler:
Cause is null
when job has completed normally.
Cause is an instance of CancellationException when job was cancelled normally. It should not be treated as an error. In particular, it should not be reported to error logs.
Otherwise, the job had failed.
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 CompletionHandlerException, and rethrown, potentially causing crash of unrelated code.
Note: Implementations of CompletionHandler
must be fast and lock-free.