cancellation
Stopping/Cancelling scopes are independent of each other
From Stopping/Cancelling scopes have independent cancellations
Go to text ā
In short cancelling one co-routine scope does not cancel other co-routine scopes. Other co-routines can continue to run, if they are not cancelled.
Code
package com.glassthought.sandbox
import gt.sandbox.util.output.Out
import kotlinx.coroutines.*
interface Server {
suspend fun start()
suspend fun stop()
suspend fun join()
}
val out = Out.standard()
class ServerImpl(
private val serverName: String,
private val scope: CoroutineScope // Injected scope for better control
) : Server {
private var backgroundJob: Job? = null
override suspend fun start() {
out.info("Starting server")
backgroundJob = scope.launch(CoroutineName("${serverName}-work-1")) {
out.info("Running server work in thread: ${Thread.currentThread().name}")
launch {
out.info("${serverName}: spawned from background job - work-A")
delay(3000)
out.info("${serverName}-work-A completed")
}
delay(2000)
out.info("${serverName}-work-1 completed")
}
}
override suspend fun stop() {
out.info("Stopping server: $serverName")
scope.cancel()
}
override suspend fun join() {
if (backgroundJob != null) {
backgroundJob!!.join()
}
}
}
fun main() = runBlocking {
val server1 = ServerImpl("server-1", CoroutineScope(Dispatchers.Default))
val server2 = ServerImpl("server-2", CoroutineScope(Dispatchers.Default))
server1.start()
server2.start()
delay(10)
// Stopping server 1 should not stop server - 2
server1.stop()
server1.join()
server2.join()
out.info("Main completed")
}
Command to reproduce:
gt.sandbox.checkout.commit 270036abdbf76a97afd3 \
&& cd "${GT_SANDBOX_REPO}" \
&& cmd.run.announce "./gradlew run --quiet"
Recorded output of command:
[elapsed: 39ms][š„/tname:main/tid:1][coroutine:unnamed] Starting server
[elapsed: 57ms][š„/tname:main/tid:1][coroutine:unnamed] Starting server
[elapsed: 57ms][ā¶/tname:DefaultDispatcher-worker-1/tid:20][coroutine:server-1-work-1] Running server work in thread: DefaultDispatcher-worker-1
[elapsed: 57ms][ā·/tname:DefaultDispatcher-worker-2/tid:21][coroutine:server-2-work-1] Running server work in thread: DefaultDispatcher-worker-2
[elapsed: 59ms][āø/tname:DefaultDispatcher-worker-3/tid:22][coroutine:server-1-work-1] server-1: spawned from background job - work-A
[elapsed: 59ms][ā¹/tname:DefaultDispatcher-worker-4/tid:23][coroutine:server-2-work-1] server-2: spawned from background job - work-A
[elapsed: 71ms][š„/tname:main/tid:1][coroutine:unnamed] Stopping server: server-1
[elapsed: 2065ms][ā·/tname:DefaultDispatcher-worker-2/tid:21][coroutine:server-2-work-1] server-2-work-1 completed
[elapsed: 3063ms][ā·/tname:DefaultDispatcher-worker-2/tid:21][coroutine:server-2-work-1] server-2-work-A completed
[elapsed: 3064ms][š„/tname:main/tid:1][coroutine:unnamed] Main completed
Children