or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

channels.mdcoroutine-builders.mddispatchers.mdexception-handling.mdflow-api.mdindex.mdjob-management.mdjvm-integration.mdsynchronization.md

job-management.mddocs/

0

# Job Management

1

2

Lifecycle management for coroutines providing hierarchical cancellation, completion tracking, and structured concurrency with parent-child relationships.

3

4

## Capabilities

5

6

### Job Interface

7

8

Represents a cancellable background job with a well-defined lifecycle and states.

9

10

```kotlin { .api }

11

interface Job : CoroutineContext.Element {

12

/** True if job is active and running */

13

val isActive: Boolean

14

15

/** True if job has completed (successfully or with failure) */

16

val isCompleted: Boolean

17

18

/** True if job was cancelled */

19

val isCancelled: Boolean

20

21

/** Sequence of all child jobs */

22

val children: Sequence<Job>

23

24

/** Starts the job if it was created in lazy state */

25

fun start(): Boolean

26

27

/** Cancels the job with optional cause */

28

fun cancel(cause: CancellationException? = null)

29

30

/** Suspends until job completion */

31

suspend fun join()

32

33

/** Select clause for join operation */

34

val onJoin: SelectClause0

35

36

/** Registers completion handler */

37

fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle

38

39

/** Cancels job and suspends until completion */

40

suspend fun cancelAndJoin()

41

}

42

43

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

44

```

45

46

**Job States:**

47

48

| State | isActive | isCompleted | isCancelled |

49

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

50

| New (lazy) | `false` | `false` | `false` |

51

| Active | `true` | `false` | `false` |

52

| Completing | `true` | `false` | `false` |

53

| Cancelling | `false` | `false` | `true` |

54

| Cancelled | `false` | `true` | `true` |

55

| Completed | `false` | `true` | `false` |

56

57

**Usage Examples:**

58

59

```kotlin

60

import kotlinx.coroutines.*

61

62

fun main() = runBlocking {

63

// Basic job lifecycle

64

val job = launch {

65

repeat(5) { i ->

66

println("Working $i")

67

delay(500)

68

}

69

}

70

71

delay(1500) // Let it work for a while

72

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

73

74

job.cancel() // Cancel the job

75

job.join() // Wait for cancellation to complete

76

77

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

78

}

79

80

// Completion handler example

81

fun jobWithCompletionHandler() = runBlocking {

82

val job = launch {

83

try {

84

delay(1000)

85

println("Job completed normally")

86

} catch (e: CancellationException) {

87

println("Job was cancelled")

88

throw e

89

}

90

}

91

92

job.invokeOnCompletion { cause ->

93

if (cause != null) {

94

println("Job completed with exception: $cause")

95

} else {

96

println("Job completed successfully")

97

}

98

}

99

100

delay(500)

101

job.cancel()

102

job.join()

103

}

104

```

105

106

### Deferred Interface

107

108

A Job that produces a result value, created by `async` coroutine builder.

109

110

```kotlin { .api }

111

interface Deferred<out T> : Job {

112

/** Suspends until result is available and returns it */

113

suspend fun await(): T

114

115

/** Gets result if completed, throws if not completed or failed */

116

fun getCompleted(): T

117

118

/** Returns completion exception or null if completed successfully */

119

fun getCompletionExceptionOrNull(): Throwable?

120

121

/** Select clause for await operation */

122

val onAwait: SelectClause1<T>

123

}

124

```

125

126

**Usage Examples:**

127

128

```kotlin

129

import kotlinx.coroutines.*

130

131

fun main() = runBlocking {

132

// Single deferred

133

val deferred = async {

134

delay(1000)

135

"Hello, World!"

136

}

137

138

val result = deferred.await()

139

println(result)

140

141

// Multiple concurrent operations

142

val deferredList = List(5) { i ->

143

async {

144

delay((i + 1) * 100L)

145

"Result $i"

146

}

147

}

148

149

val results = deferredList.awaitAll()

150

println("All results: $results")

151

152

// Error handling

153

val faultyDeferred = async {

154

delay(100)

155

throw RuntimeException("Something went wrong")

156

}

157

158

try {

159

faultyDeferred.await()

160

} catch (e: RuntimeException) {

161

println("Caught exception: ${e.message}")

162

}

163

}

164

165

// Getting completed result without suspending

166

fun checkCompletedResult() = runBlocking {

167

val deferred = async {

168

delay(100)

169

42

170

}

171

172

delay(200) // Ensure completion

173

174

if (deferred.isCompleted) {

175

val result = deferred.getCompleted()

176

println("Result: $result")

177

}

178

}

179

```

180

181

### CompletableJob

182

183

A Job that can be completed manually, created with `Job()` factory function.

184

185

```kotlin { .api }

186

interface CompletableJob : Job {

187

/** Completes the job successfully */

188

fun complete(): Boolean

189

190

/** Completes the job with exception */

191

fun completeExceptionally(exception: Throwable): Boolean

192

}

193

194

/** Creates a new CompletableJob */

195

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

196

```

197

198

**Usage Examples:**

199

200

```kotlin

201

import kotlinx.coroutines.*

202

203

fun main() = runBlocking {

204

// Manual job completion

205

val job = Job()

206

207

launch {

208

job.join()

209

println("Job completed!")

210

}

211

212

delay(1000)

213

job.complete() // Manually complete the job

214

215

// CompletableJob with parent

216

val parentJob = Job()

217

val childJob = Job(parentJob)

218

219

launch {

220

childJob.join()

221

println("Child job completed")

222

}

223

224

launch {

225

parentJob.join()

226

println("Parent job completed")

227

}

228

229

childJob.complete()

230

parentJob.complete()

231

}

232

233

// Error completion example

234

fun errorCompletionExample() = runBlocking {

235

val job = Job()

236

237

launch {

238

try {

239

job.join()

240

println("Should not reach here")

241

} catch (e: Exception) {

242

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

243

}

244

}

245

246

delay(100)

247

job.completeExceptionally(RuntimeException("Manual failure"))

248

}

249

```

250

251

### SupervisorJob

252

253

A special job that doesn't cancel its parent when its children fail, enabling supervisor pattern for fault tolerance.

254

255

```kotlin { .api }

256

/** Creates a supervisor job that doesn't propagate child failures */

257

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

258

259

/** Creates a supervisor scope where child failures don't cancel siblings */

260

suspend fun <T> supervisorScope(

261

block: suspend CoroutineScope.() -> T

262

): T

263

```

264

265

**Usage Examples:**

266

267

```kotlin

268

import kotlinx.coroutines.*

269

270

fun main() = runBlocking {

271

// SupervisorJob example

272

val supervisor = SupervisorJob()

273

274

launch(supervisor) {

275

launch {

276

delay(100)

277

throw RuntimeException("Child 1 failed")

278

}

279

280

launch {

281

delay(200)

282

println("Child 2 completed successfully")

283

}

284

285

launch {

286

delay(300)

287

println("Child 3 completed successfully")

288

}

289

}

290

291

delay(500)

292

supervisor.complete()

293

}

294

295

// supervisorScope example

296

suspend fun processItems(items: List<String>) = supervisorScope {

297

items.map { item ->

298

async {

299

if (item == "fail") {

300

throw RuntimeException("Failed to process $item")

301

}

302

"Processed $item"

303

}

304

}.mapNotNull { deferred ->

305

try {

306

deferred.await()

307

} catch (e: Exception) {

308

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

309

null // Continue with other items

310

}

311

}

312

}

313

```

314

315

### Job Hierarchy and Cancellation

316

317

Understanding parent-child relationships and cancellation propagation.

318

319

```kotlin { .api }

320

/** Extension property to get job from coroutine context */

321

val CoroutineContext.job: Job

322

323

/** Extension property to check if context is active */

324

val CoroutineContext.isActive: Boolean

325

326

/** Ensures the context is active, throws CancellationException if cancelled */

327

fun CoroutineContext.ensureActive()

328

329

/** Cancellation exception for cooperative cancellation */

330

class CancellationException(

331

message: String? = null,

332

cause: Throwable? = null

333

) : IllegalStateException(message, cause)

334

```

335

336

**Usage Examples:**

337

338

```kotlin

339

import kotlinx.coroutines.*

340

341

fun main() = runBlocking {

342

// Parent-child cancellation

343

val parentJob = launch {

344

val child1 = launch {

345

try {

346

repeat(10) { i ->

347

delay(100)

348

println("Child 1: $i")

349

}

350

} catch (e: CancellationException) {

351

println("Child 1 cancelled")

352

throw e

353

}

354

}

355

356

val child2 = launch {

357

try {

358

repeat(10) { i ->

359

delay(150)

360

println("Child 2: $i")

361

}

362

} catch (e: CancellationException) {

363

println("Child 2 cancelled")

364

throw e

365

}

366

}

367

368

delay(500)

369

println("Parent completing")

370

}

371

372

delay(300)

373

parentJob.cancel() // Cancels all children too

374

parentJob.join()

375

}

376

377

// Cooperative cancellation

378

suspend fun cooperativeCancellation() {

379

repeat(1000) { i ->

380

// Check for cancellation

381

if (!coroutineContext.isActive) {

382

println("Detected cancellation at iteration $i")

383

return

384

}

385

386

// Or use ensureActive() which throws CancellationException

387

coroutineContext.ensureActive()

388

389

// Simulate work

390

Thread.sleep(10)

391

}

392

}

393

```

394

395

## Types

396

397

### DisposableHandle

398

399

Handle for cleanup operations that can be disposed.

400

401

```kotlin { .api }

402

interface DisposableHandle {

403

/** Disposes of the resource */

404

fun dispose()

405

}

406

```

407

408

### Select Clause Types

409

410

Types used for select expressions in coroutine operations.

411

412

```kotlin { .api }

413

/** Base interface for select clauses */

414

sealed interface SelectClause

415

416

/** Select clause without parameters that doesn't select any value */

417

sealed interface SelectClause0 : SelectClause

418

419

/** Select clause without parameters that selects value of type T */

420

sealed interface SelectClause1<out T> : SelectClause

421

422

/** Select clause with parameter P that selects value of type Q */

423

sealed interface SelectClause2<in P, out Q> : SelectClause

424

```

425

426

### CoroutineContext Elements

427

428

Job-related context elements for coroutine management.

429

430

```kotlin { .api }

431

/** Context element key for Job */

432

object Job : CoroutineContext.Key<Job>

433

434

/** Creates a new job context element */

435

fun Job(): CompletableJob

436

```