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

coroutine-builders.mddocs/

0

# Coroutine Builders and Scopes

1

2

Core building blocks for creating and managing coroutines with structured concurrency guarantees. These provide the foundation for launching concurrent operations and managing their lifecycle.

3

4

## Capabilities

5

6

### CoroutineScope Interface

7

8

The fundamental interface that defines a scope for coroutines, providing context inheritance and structured concurrency.

9

10

```kotlin { .api }

11

/**

12

* Defines a scope for new coroutines. Every coroutine builder is an extension

13

* on CoroutineScope and inherits its coroutineContext to automatically

14

* propagate all context elements and cancellation.

15

*/

16

interface CoroutineScope {

17

/**

18

* The context of this scope.

19

* Context is encapsulated by the scope and used for implementation of coroutine builders.

20

*/

21

val coroutineContext: CoroutineContext

22

}

23

24

/**

25

* Adds the specified coroutine context to this scope, overriding existing elements

26

* in the current scope's context with the corresponding keys.

27

*/

28

operator fun CoroutineScope.plus(context: CoroutineContext): CoroutineScope

29

```

30

31

### Launch Builder

32

33

Creates and starts a coroutine that doesn't return a result, ideal for fire-and-forget operations.

34

35

```kotlin { .api }

36

/**

37

* Launches a new coroutine without blocking the current thread and returns

38

* a reference to the coroutine as a Job. The coroutine is cancelled when

39

* the resulting job is cancelled.

40

*

41

* @param context additional to CoroutineScope.coroutineContext context of the coroutine

42

* @param start coroutine start option. The default value is CoroutineStart.DEFAULT

43

* @param block the coroutine code which will be invoked in the context of the provided scope

44

*/

45

fun CoroutineScope.launch(

46

context: CoroutineContext = EmptyCoroutineContext,

47

start: CoroutineStart = CoroutineStart.DEFAULT,

48

block: suspend CoroutineScope.() -> Unit

49

): Job

50

```

51

52

**Usage Examples:**

53

54

```kotlin

55

import kotlinx.coroutines.*

56

57

val scope = MainScope()

58

59

// Basic launch

60

val job = scope.launch {

61

delay(1000)

62

println("Task completed!")

63

}

64

65

// Launch with custom context

66

val job2 = scope.launch(Dispatchers.IO) {

67

// Perform I/O operations

68

println("Running on IO dispatcher")

69

}

70

71

// Launch with lazy start

72

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

73

println("This won't run until started")

74

}

75

lazyJob.start() // Explicitly start the lazy coroutine

76

77

// Launch with custom name for debugging

78

val namedJob = scope.launch(CoroutineName("DataProcessor")) {

79

println("Processing data...")

80

}

81

```

82

83

### Async Builder

84

85

Creates a coroutine that computes and returns a result, returning a Deferred that can be awaited.

86

87

```kotlin { .api }

88

/**

89

* Creates a coroutine and returns its future result as an implementation of Deferred.

90

* The running coroutine is cancelled when the resulting deferred is cancelled.

91

*

92

* @param context additional to CoroutineScope.coroutineContext context of the coroutine

93

* @param start coroutine start option. The default value is CoroutineStart.DEFAULT

94

* @param block the coroutine code

95

*/

96

fun <T> CoroutineScope.async(

97

context: CoroutineContext = EmptyCoroutineContext,

98

start: CoroutineStart = CoroutineStart.DEFAULT,

99

block: suspend CoroutineScope.() -> T

100

): Deferred<T>

101

```

102

103

**Usage Examples:**

104

105

```kotlin

106

import kotlinx.coroutines.*

107

108

val scope = MainScope()

109

110

// Basic async operation

111

val deferred = scope.async {

112

delay(1000)

113

"Hello from async!"

114

}

115

116

scope.launch {

117

val result = deferred.await()

118

println(result) // Prints: Hello from async!

119

}

120

121

// Multiple concurrent operations

122

val results = scope.async {

123

val task1 = async { computeTask1() }

124

val task2 = async { computeTask2() }

125

val task3 = async { computeTask3() }

126

127

// Wait for all tasks to complete

128

listOf(task1.await(), task2.await(), task3.await())

129

}

130

131

// Async with error handling

132

val deferredWithErrorHandling = scope.async {

133

try {

134

riskyOperation()

135

} catch (e: Exception) {

136

"Fallback result"

137

}

138

}

139

```

140

141

### Scope Factory Functions

142

143

Functions for creating new coroutine scopes with specific configurations.

144

145

```kotlin { .api }

146

/**

147

* Creates a CoroutineScope that wraps the given coroutine context.

148

* If the given context does not contain a Job element, then a default Job() is created.

149

*

150

* @param context the coroutine context for the new scope

151

*/

152

fun CoroutineScope(context: CoroutineContext): CoroutineScope

153

154

/**

155

* Creates a CoroutineScope for main thread operations.

156

* Uses Dispatchers.Main for its coroutines and has a SupervisorJob.

157

*/

158

fun MainScope(): CoroutineScope

159

```

160

161

**Usage Examples:**

162

163

```kotlin

164

import kotlinx.coroutines.*

165

166

// Create a scope with custom context

167

val customScope = CoroutineScope(Dispatchers.Default + CoroutineName("MyScope"))

168

169

// Create a main scope for UI operations

170

val mainScope = MainScope()

171

172

// Create a scope with supervisor job (failures don't cancel siblings)

173

val supervisorScope = CoroutineScope(SupervisorJob() + Dispatchers.Default)

174

175

// Remember to cancel scopes when done

176

class MyClass {

177

private val scope = MainScope()

178

179

fun cleanup() {

180

scope.cancel()

181

}

182

}

183

```

184

185

### GlobalScope

186

187

A global coroutine scope not bound to any job (use with extreme caution).

188

189

```kotlin { .api }

190

/**

191

* A global CoroutineScope not bound to any job.

192

*

193

* Global scope is used to launch top-level coroutines which are operating on the

194

* whole application lifetime and are not cancelled prematurely.

195

*

196

* Application code usually should use an application-defined CoroutineScope,

197

* using async or launch on the instance of GlobalScope is highly discouraged.

198

*/

199

object GlobalScope : CoroutineScope

200

```

201

202

**Warning:** GlobalScope should be used sparingly as it can lead to resource leaks and makes testing difficult.

203

204

### Await Utility Functions

205

206

Convenience functions for waiting on multiple coroutines.

207

208

```kotlin { .api }

209

/**

210

* Awaits for completion of given deferred values without blocking a thread

211

* and returns a list of resulting values.

212

*/

213

suspend fun <T> awaitAll(vararg deferreds: Deferred<T>): List<T>

214

215

/**

216

* Suspends current coroutine until all given jobs are complete.

217

*/

218

suspend fun joinAll(vararg jobs: Job)

219

```

220

221

**Usage Examples:**

222

223

```kotlin

224

import kotlinx.coroutines.*

225

226

val scope = MainScope()

227

228

scope.launch {

229

// Wait for multiple async operations

230

val task1 = async { fetchUserData() }

231

val task2 = async { fetchUserPosts() }

232

val task3 = async { fetchUserSettings() }

233

234

val results = awaitAll(task1, task2, task3)

235

val (userData, userPosts, userSettings) = results

236

237

// Process combined results

238

displayUserProfile(userData, userPosts, userSettings)

239

}

240

241

scope.launch {

242

// Wait for multiple jobs to complete

243

val job1 = launch { updateDatabase() }

244

val job2 = launch { clearCache() }

245

val job3 = launch { notifyUsers() }

246

247

joinAll(job1, job2, job3)

248

println("All maintenance tasks completed!")

249

}

250

```

251

252

## Coroutine Start Options

253

254

```kotlin { .api }

255

/**

256

* Defines start options for coroutines builders.

257

*/

258

enum class CoroutineStart {

259

/**

260

* Default -- immediately schedules coroutine for execution according to its context.

261

*/

262

DEFAULT,

263

264

/**

265

* Lazily -- starts coroutine lazily, only when it is needed.

266

*/

267

LAZY,

268

269

/**

270

* Atomically -- atomically (in a non-cancellable way) schedules coroutine for execution.

271

*/

272

ATOMIC,

273

274

/**

275

* Immediately executes coroutine until its first suspension point in the current thread.

276

*/

277

UNDISPATCHED

278

}

279

```

280

281

**Usage Examples:**

282

283

```kotlin

284

import kotlinx.coroutines.*

285

286

val scope = MainScope()

287

288

// Lazy start - coroutine won't run until explicitly started

289

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

290

println("This runs only when explicitly started")

291

}

292

// Later...

293

lazyJob.start()

294

295

// ATOMIC start - cannot be cancelled before first suspension

296

val atomicJob = scope.launch(start = CoroutineStart.ATOMIC) {

297

println("This will definitely print even if cancelled immediately")

298

delay(100) // First suspension point - cancellation can happen after this

299

}

300

301

// UNDISPATCHED - runs immediately in current thread until first suspension

302

val undispatchedJob = scope.launch(start = CoroutineStart.UNDISPATCHED) {

303

println("This runs immediately in current thread")

304

delay(100) // Will be dispatched according to context after this suspension

305

}

306

```