CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-jetbrains-kotlinx--kotlinx-coroutines-core

Coroutines support libraries for Kotlin providing structured concurrency primitives, Flow API for reactive streams, channels for communication, and synchronization utilities across all Kotlin platforms

Pending
Overview
Eval results
Files

jobs-deferreds.mddocs/

Jobs and Deferreds

Lifecycle management for coroutines including cancellation, completion tracking, and result handling. These interfaces provide the foundation for structured concurrency and coroutine coordination.

Capabilities

Job Interface

The fundamental interface representing a cancellable background task with a well-defined lifecycle.

/**
 * A background job. Conceptually, a job is a cancellable thing with a lifecycle
 * that concludes in its completion.
 */
interface Job : CoroutineContext.Element {
    /**
     * Returns true when this job is active -- it was already started and has not
     * completed nor was cancelled yet.
     */
    val isActive: Boolean
    
    /**
     * Returns true when this job has completed for any reason.
     */
    val isCompleted: Boolean
    
    /**
     * Returns true if this job was cancelled. A job becomes cancelled when it
     * finishes with a CancellationException.
     */
    val isCancelled: Boolean
    
    /**
     * Returns a sequence of this job's children.
     */
    val children: Sequence<Job>
    
    /**
     * Starts this job if it was created with CoroutineStart.LAZY.
     * Returns true if job was started by this call, false if it was already started.
     */
    fun start(): Boolean
    
    /**
     * Cancels this job with an optional cancellation cause.
     * A cause can be used to specify an error message or to provide other details.
     */
    fun cancel(cause: CancellationException? = null)
    
    /**
     * Suspends current coroutine until this job is complete.
     */
    suspend fun join()
    
    /**
     * Registers a completion handler for this job.
     */
    fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle
    
    /**
     * Registers a completion handler for this job.
     */
    fun invokeOnCompletion(
        onCancelling: Boolean = false,
        invokeImmediately: Boolean = true,
        handler: CompletionHandler
    ): DisposableHandle
}

/**
 * Handler for Job completion.
 */
typealias CompletionHandler = (cause: Throwable?) -> Unit

/**
 * Represents a disposable resource that can be disposed/cancelled.
 */
interface DisposableHandle {
    fun dispose()
}

Usage Examples:

import kotlinx.coroutines.*

val scope = MainScope()

// Basic job lifecycle management
val job = scope.launch {
    repeat(10) { i ->
        println("Working... $i")
        delay(500)
    }
}

// Check job status
println("Job is active: ${job.isActive}")
println("Job is completed: ${job.isCompleted}")

// Cancel the job
scope.launch {
    delay(2000)
    job.cancel()
    println("Job cancelled")
}

// Wait for job completion
scope.launch {
    job.join()
    println("Job finished")
}

// Register completion handler
val disposable = job.invokeOnCompletion { cause ->
    when (cause) {
        null -> println("Job completed successfully")
        is CancellationException -> println("Job was cancelled")
        else -> println("Job failed with exception: $cause")
    }
}

Deferred Interface

A Job that produces a result value, representing a non-blocking cancellable future.

/**
 * Deferred value is a non-blocking cancellable future — it is a Job with a result.
 * It is created with the async coroutine builder.
 */
interface Deferred<out T> : Job {
    /**
     * Awaits for completion of this value without blocking the thread and returns
     * the resulting value or throws the exception if the deferred was cancelled.
     */
    suspend fun await(): T
    
    /**
     * Returns completed result or throws IllegalStateException if this deferred
     * value has not completed yet.
     */
    fun getCompleted(): T
    
    /**
     * Clause using the await suspending function as a select clause.
     */
    val onAwait: SelectClause1<T>
}

Usage Examples:

import kotlinx.coroutines.*

val scope = MainScope()

// Basic deferred usage
val deferred = scope.async {
    delay(1000)
    "Hello World"
}

scope.launch {
    try {
        val result = deferred.await()
        println("Result: $result")
    } catch (e: CancellationException) {
        println("Deferred was cancelled")
    }
}

// Multiple deferreds
scope.launch {
    val task1 = async { computeValue1() }
    val task2 = async { computeValue2() }
    val task3 = async { computeValue3() }
    
    // Wait for all and collect results
    val results = listOf(task1.await(), task2.await(), task3.await())
    println("All results: $results")
}

// Non-blocking result access (only if completed)
val immediateDeferred = scope.async { 42 }
delay(100) // Ensure completion
if (immediateDeferred.isCompleted) {
    val value = immediateDeferred.getCompleted()
    println("Immediate result: $value")
}

CompletableJob Interface

A Job that can be completed manually, providing explicit control over job lifecycle.

/**
 * A Job that can be completed using CompletableJob.complete() function.
 * It is returned by Job() constructor function.
 */
interface CompletableJob : Job {
    /**
     * Completes this job. The result is true if this job was completed as
     * a result of this invocation and false if it was already completed.
     */
    fun complete(): Boolean
    
    /**
     * Completes this job exceptionally with the specified exception.
     * The result is true if this job was completed as a result of this invocation
     * and false if it was already completed.
     */
    fun completeExceptionally(exception: Throwable): Boolean
}

/**
 * Creates a job object in an active state.
 * A failure of any child of this job immediately causes this job to fail too
 * and cancels the rest of its children.
 */
fun Job(parent: Job? = null): CompletableJob

Usage Examples:

import kotlinx.coroutines.*

val scope = MainScope()

// Manual job completion
val completableJob = Job()

scope.launch {
    try {
        completableJob.join()
        println("Job completed successfully!")
    } catch (e: CancellationException) {
        println("Job was cancelled")
    }
}

// Complete the job manually after some work
scope.launch {
    delay(1000)
    // Do some work...
    completableJob.complete()
}

// Job with parent-child relationship
val parentJob = Job()
val childJob = Job(parent = parentJob)

// If parent is cancelled, child is automatically cancelled
scope.launch {
    delay(500)
    parentJob.cancel()
    // childJob is now also cancelled
}

// Exception completion
val jobWithException = Job()
scope.launch {
    try {
        jobWithException.join()
    } catch (e: Exception) {
        println("Job failed: ${e.message}")
    }
}

scope.launch {
    delay(1000)
    jobWithException.completeExceptionally(RuntimeException("Something went wrong"))
}

CompletableDeferred Interface

A Deferred that can be completed manually, combining the features of Deferred and CompletableJob.

/**
 * A Deferred that can be completed via complete() and completeExceptionally() functions.
 */
interface CompletableDeferred<T> : Deferred<T>, CompletableJob {
    /**
     * Completes this deferred with a given value.
     */
    fun complete(value: T): Boolean
    
    /**
     * Completes this deferred exceptionally with a given exception.
     */
    override fun completeExceptionally(exception: Throwable): Boolean
}

/**
 * Creates a CompletableDeferred in an active state.
 */
fun <T> CompletableDeferred(parent: Job? = null): CompletableDeferred<T>

Usage Examples:

import kotlinx.coroutines.*

val scope = MainScope()

// Manual deferred completion
val completableDeferred = CompletableDeferred<String>()

scope.launch {
    try {
        val result = completableDeferred.await()
        println("Received result: $result")
    } catch (e: Exception) {
        println("Deferred failed: ${e.message}")
    }
}

// Complete with value after some async work
scope.launch {
    delay(1000)
    val computedValue = "Computed result"
    completableDeferred.complete(computedValue)
}

// Bridge callback-based APIs
fun fetchDataWithCallback(callback: (String?, Exception?) -> Unit) {
    // Simulate async operation
    scope.launch {
        delay(500)
        if (Math.random() > 0.5) {
            callback("Success data", null)
        } else {
            callback(null, RuntimeException("Network error"))
        }
    }
}

suspend fun fetchDataSuspending(): String {
    val deferred = CompletableDeferred<String>()
    
    fetchDataWithCallback { data, error ->
        if (error != null) {
            deferred.completeExceptionally(error)
        } else {
            deferred.complete(data!!)
        }
    }
    
    return deferred.await()
}

SupervisorJob

A special job type that does not cancel other children when one child fails.

/**
 * Creates a supervisor job object in an active state.
 * Children of a supervisor job can fail independently of each other.
 */
fun SupervisorJob(parent: Job? = null): CompletableJob

Usage Examples:

import kotlinx.coroutines.*

val scope = MainScope()

// Regular job - child failure cancels siblings
val regularJob = Job()
val scopeWithRegularJob = CoroutineScope(regularJob + Dispatchers.Default)

scopeWithRegularJob.launch {
    delay(2000)
    println("Task 1 completed") // This won't print if task 2 fails
}

scopeWithRegularJob.launch {
    delay(1000)
    throw RuntimeException("Task 2 failed") // This cancels task 1
}

// Supervisor job - child failures are independent
val supervisorJob = SupervisorJob()
val scopeWithSupervisor = CoroutineScope(supervisorJob + Dispatchers.Default)

scopeWithSupervisor.launch {
    delay(2000)
    println("Task A completed") // This will print even if task B fails
}

scopeWithSupervisor.launch {
    delay(1000)
    throw RuntimeException("Task B failed") // This doesn't affect task A
}

// Handle individual failures in supervisor scope
scopeWithSupervisor.launch {
    try {
        riskyOperation()
    } catch (e: Exception) {
        println("Task failed but others continue: ${e.message}")
    }
}

Job State Management

Understanding job states and lifecycle transitions.

Job States:

StateisActiveisCompletedisCancelled
New (optional)falsefalsefalse
Active (default)truefalsefalse
Completingtruefalsefalse
Cancellingfalsefalsetrue
Cancelledfalsetruetrue
Completedfalsetruefalse

Usage Examples:

import kotlinx.coroutines.*

val scope = MainScope()

// Monitor job state changes
val job = scope.launch(start = CoroutineStart.LAZY) {
    println("Job started")
    delay(1000)
    println("Job work completed")
}

println("Initial state - Active: ${job.isActive}, Completed: ${job.isCompleted}, Cancelled: ${job.isCancelled}")

// Start the lazy job
job.start()
println("After start - Active: ${job.isActive}, Completed: ${job.isCompleted}, Cancelled: ${job.isCancelled}")

// Wait a bit then cancel
scope.launch {
    delay(500)
    job.cancel()
    println("After cancel - Active: ${job.isActive}, Completed: ${job.isCompleted}, Cancelled: ${job.isCancelled}")
}

// Wait for completion
scope.launch {
    job.join()
    println("After join - Active: ${job.isActive}, Completed: ${job.isCompleted}, Cancelled: ${job.isCancelled}")
}

Install with Tessl CLI

npx tessl i tessl/maven-org-jetbrains-kotlinx--kotlinx-coroutines-core

docs

channels.md

coroutine-builders.md

dispatchers.md

exception-handling.md

flow-api.md

index.md

jobs-deferreds.md

structured-concurrency.md

synchronization.md

tile.json