or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

channels.mdcoroutine-builders.mddispatchers.mdexception-handling.mdflow-api.mdindex.mdjobs-deferreds.mdstructured-concurrency.mdsynchronization.md

jobs-deferreds.mddocs/

0

# Jobs and Deferreds

1

2

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

3

4

## Capabilities

5

6

### Job Interface

7

8

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

9

10

```kotlin { .api }

11

/**

12

* A background job. Conceptually, a job is a cancellable thing with a lifecycle

13

* that concludes in its completion.

14

*/

15

interface Job : CoroutineContext.Element {

16

/**

17

* Returns true when this job is active -- it was already started and has not

18

* completed nor was cancelled yet.

19

*/

20

val isActive: Boolean

21

22

/**

23

* Returns true when this job has completed for any reason.

24

*/

25

val isCompleted: Boolean

26

27

/**

28

* Returns true if this job was cancelled. A job becomes cancelled when it

29

* finishes with a CancellationException.

30

*/

31

val isCancelled: Boolean

32

33

/**

34

* Returns a sequence of this job's children.

35

*/

36

val children: Sequence<Job>

37

38

/**

39

* Starts this job if it was created with CoroutineStart.LAZY.

40

* Returns true if job was started by this call, false if it was already started.

41

*/

42

fun start(): Boolean

43

44

/**

45

* Cancels this job with an optional cancellation cause.

46

* A cause can be used to specify an error message or to provide other details.

47

*/

48

fun cancel(cause: CancellationException? = null)

49

50

/**

51

* Suspends current coroutine until this job is complete.

52

*/

53

suspend fun join()

54

55

/**

56

* Registers a completion handler for this job.

57

*/

58

fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle

59

60

/**

61

* Registers a completion handler for this job.

62

*/

63

fun invokeOnCompletion(

64

onCancelling: Boolean = false,

65

invokeImmediately: Boolean = true,

66

handler: CompletionHandler

67

): DisposableHandle

68

}

69

70

/**

71

* Handler for Job completion.

72

*/

73

typealias CompletionHandler = (cause: Throwable?) -> Unit

74

75

/**

76

* Represents a disposable resource that can be disposed/cancelled.

77

*/

78

interface DisposableHandle {

79

fun dispose()

80

}

81

```

82

83

**Usage Examples:**

84

85

```kotlin

86

import kotlinx.coroutines.*

87

88

val scope = MainScope()

89

90

// Basic job lifecycle management

91

val job = scope.launch {

92

repeat(10) { i ->

93

println("Working... $i")

94

delay(500)

95

}

96

}

97

98

// Check job status

99

println("Job is active: ${job.isActive}")

100

println("Job is completed: ${job.isCompleted}")

101

102

// Cancel the job

103

scope.launch {

104

delay(2000)

105

job.cancel()

106

println("Job cancelled")

107

}

108

109

// Wait for job completion

110

scope.launch {

111

job.join()

112

println("Job finished")

113

}

114

115

// Register completion handler

116

val disposable = job.invokeOnCompletion { cause ->

117

when (cause) {

118

null -> println("Job completed successfully")

119

is CancellationException -> println("Job was cancelled")

120

else -> println("Job failed with exception: $cause")

121

}

122

}

123

```

124

125

### Deferred Interface

126

127

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

128

129

```kotlin { .api }

130

/**

131

* Deferred value is a non-blocking cancellable future — it is a Job with a result.

132

* It is created with the async coroutine builder.

133

*/

134

interface Deferred<out T> : Job {

135

/**

136

* Awaits for completion of this value without blocking the thread and returns

137

* the resulting value or throws the exception if the deferred was cancelled.

138

*/

139

suspend fun await(): T

140

141

/**

142

* Returns completed result or throws IllegalStateException if this deferred

143

* value has not completed yet.

144

*/

145

fun getCompleted(): T

146

147

/**

148

* Clause using the await suspending function as a select clause.

149

*/

150

val onAwait: SelectClause1<T>

151

}

152

```

153

154

**Usage Examples:**

155

156

```kotlin

157

import kotlinx.coroutines.*

158

159

val scope = MainScope()

160

161

// Basic deferred usage

162

val deferred = scope.async {

163

delay(1000)

164

"Hello World"

165

}

166

167

scope.launch {

168

try {

169

val result = deferred.await()

170

println("Result: $result")

171

} catch (e: CancellationException) {

172

println("Deferred was cancelled")

173

}

174

}

175

176

// Multiple deferreds

177

scope.launch {

178

val task1 = async { computeValue1() }

179

val task2 = async { computeValue2() }

180

val task3 = async { computeValue3() }

181

182

// Wait for all and collect results

183

val results = listOf(task1.await(), task2.await(), task3.await())

184

println("All results: $results")

185

}

186

187

// Non-blocking result access (only if completed)

188

val immediateDeferred = scope.async { 42 }

189

delay(100) // Ensure completion

190

if (immediateDeferred.isCompleted) {

191

val value = immediateDeferred.getCompleted()

192

println("Immediate result: $value")

193

}

194

```

195

196

### CompletableJob Interface

197

198

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

199

200

```kotlin { .api }

201

/**

202

* A Job that can be completed using CompletableJob.complete() function.

203

* It is returned by Job() constructor function.

204

*/

205

interface CompletableJob : Job {

206

/**

207

* Completes this job. The result is true if this job was completed as

208

* a result of this invocation and false if it was already completed.

209

*/

210

fun complete(): Boolean

211

212

/**

213

* Completes this job exceptionally with the specified exception.

214

* The result is true if this job was completed as a result of this invocation

215

* and false if it was already completed.

216

*/

217

fun completeExceptionally(exception: Throwable): Boolean

218

}

219

220

/**

221

* Creates a job object in an active state.

222

* A failure of any child of this job immediately causes this job to fail too

223

* and cancels the rest of its children.

224

*/

225

fun Job(parent: Job? = null): CompletableJob

226

```

227

228

**Usage Examples:**

229

230

```kotlin

231

import kotlinx.coroutines.*

232

233

val scope = MainScope()

234

235

// Manual job completion

236

val completableJob = Job()

237

238

scope.launch {

239

try {

240

completableJob.join()

241

println("Job completed successfully!")

242

} catch (e: CancellationException) {

243

println("Job was cancelled")

244

}

245

}

246

247

// Complete the job manually after some work

248

scope.launch {

249

delay(1000)

250

// Do some work...

251

completableJob.complete()

252

}

253

254

// Job with parent-child relationship

255

val parentJob = Job()

256

val childJob = Job(parent = parentJob)

257

258

// If parent is cancelled, child is automatically cancelled

259

scope.launch {

260

delay(500)

261

parentJob.cancel()

262

// childJob is now also cancelled

263

}

264

265

// Exception completion

266

val jobWithException = Job()

267

scope.launch {

268

try {

269

jobWithException.join()

270

} catch (e: Exception) {

271

println("Job failed: ${e.message}")

272

}

273

}

274

275

scope.launch {

276

delay(1000)

277

jobWithException.completeExceptionally(RuntimeException("Something went wrong"))

278

}

279

```

280

281

### CompletableDeferred Interface

282

283

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

284

285

```kotlin { .api }

286

/**

287

* A Deferred that can be completed via complete() and completeExceptionally() functions.

288

*/

289

interface CompletableDeferred<T> : Deferred<T>, CompletableJob {

290

/**

291

* Completes this deferred with a given value.

292

*/

293

fun complete(value: T): Boolean

294

295

/**

296

* Completes this deferred exceptionally with a given exception.

297

*/

298

override fun completeExceptionally(exception: Throwable): Boolean

299

}

300

301

/**

302

* Creates a CompletableDeferred in an active state.

303

*/

304

fun <T> CompletableDeferred(parent: Job? = null): CompletableDeferred<T>

305

```

306

307

**Usage Examples:**

308

309

```kotlin

310

import kotlinx.coroutines.*

311

312

val scope = MainScope()

313

314

// Manual deferred completion

315

val completableDeferred = CompletableDeferred<String>()

316

317

scope.launch {

318

try {

319

val result = completableDeferred.await()

320

println("Received result: $result")

321

} catch (e: Exception) {

322

println("Deferred failed: ${e.message}")

323

}

324

}

325

326

// Complete with value after some async work

327

scope.launch {

328

delay(1000)

329

val computedValue = "Computed result"

330

completableDeferred.complete(computedValue)

331

}

332

333

// Bridge callback-based APIs

334

fun fetchDataWithCallback(callback: (String?, Exception?) -> Unit) {

335

// Simulate async operation

336

scope.launch {

337

delay(500)

338

if (Math.random() > 0.5) {

339

callback("Success data", null)

340

} else {

341

callback(null, RuntimeException("Network error"))

342

}

343

}

344

}

345

346

suspend fun fetchDataSuspending(): String {

347

val deferred = CompletableDeferred<String>()

348

349

fetchDataWithCallback { data, error ->

350

if (error != null) {

351

deferred.completeExceptionally(error)

352

} else {

353

deferred.complete(data!!)

354

}

355

}

356

357

return deferred.await()

358

}

359

```

360

361

### SupervisorJob

362

363

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

364

365

```kotlin { .api }

366

/**

367

* Creates a supervisor job object in an active state.

368

* Children of a supervisor job can fail independently of each other.

369

*/

370

fun SupervisorJob(parent: Job? = null): CompletableJob

371

```

372

373

**Usage Examples:**

374

375

```kotlin

376

import kotlinx.coroutines.*

377

378

val scope = MainScope()

379

380

// Regular job - child failure cancels siblings

381

val regularJob = Job()

382

val scopeWithRegularJob = CoroutineScope(regularJob + Dispatchers.Default)

383

384

scopeWithRegularJob.launch {

385

delay(2000)

386

println("Task 1 completed") // This won't print if task 2 fails

387

}

388

389

scopeWithRegularJob.launch {

390

delay(1000)

391

throw RuntimeException("Task 2 failed") // This cancels task 1

392

}

393

394

// Supervisor job - child failures are independent

395

val supervisorJob = SupervisorJob()

396

val scopeWithSupervisor = CoroutineScope(supervisorJob + Dispatchers.Default)

397

398

scopeWithSupervisor.launch {

399

delay(2000)

400

println("Task A completed") // This will print even if task B fails

401

}

402

403

scopeWithSupervisor.launch {

404

delay(1000)

405

throw RuntimeException("Task B failed") // This doesn't affect task A

406

}

407

408

// Handle individual failures in supervisor scope

409

scopeWithSupervisor.launch {

410

try {

411

riskyOperation()

412

} catch (e: Exception) {

413

println("Task failed but others continue: ${e.message}")

414

}

415

}

416

```

417

418

### Job State Management

419

420

Understanding job states and lifecycle transitions.

421

422

**Job States:**

423

424

| State | isActive | isCompleted | isCancelled |

425

|-------|----------|-------------|-------------|

426

| New (optional) | false | false | false |

427

| Active (default) | true | false | false |

428

| Completing | true | false | false |

429

| Cancelling | false | false | true |

430

| Cancelled | false | true | true |

431

| Completed | false | true | false |

432

433

**Usage Examples:**

434

435

```kotlin

436

import kotlinx.coroutines.*

437

438

val scope = MainScope()

439

440

// Monitor job state changes

441

val job = scope.launch(start = CoroutineStart.LAZY) {

442

println("Job started")

443

delay(1000)

444

println("Job work completed")

445

}

446

447

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

448

449

// Start the lazy job

450

job.start()

451

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

452

453

// Wait a bit then cancel

454

scope.launch {

455

delay(500)

456

job.cancel()

457

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

458

}

459

460

// Wait for completion

461

scope.launch {

462

job.join()

463

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

464

}

465

```