GT-Sandbox-Snapshot: Example - 1, Cancelling using SupervisorJob
Code
package com.glassthought.sandboximport gt.sandbox.util.output.Outimport kotlinx.coroutines.*interface Server { suspend fun start() suspend fun stop()}val out = Out.standard()class ServerImpl( private val scope: CoroutineScope // Injected scope for better control) : Server { private val job = SupervisorJob() // Ensures independent coroutines private val serverScope = scope + job override suspend fun start() { out.info("Starting server") serverScope.launch(CoroutineName("ServerWork-1")) { out.info("Running server work in thread: ${Thread.currentThread().name}") delay(2000) out.info("ServerWork-1 completed") } serverScope.launch(CoroutineName("ServerWork-2")) { out.info("Running additional server work in thread: ${Thread.currentThread().name}") delay(1500) out.info("ServerWork-2 completed") } } override suspend fun stop() { out.info("Stopping server") job.cancel() }}fun main() = runBlocking { out.info("--------------------------------------------------------------------------------") out.info("Example where the server is aborted prior to finishing:") runWithDelayBeforeStopping(1000) out.info("--------------------------------------------------------------------------------") out.info("Example where the server has time to finish:") runWithDelayBeforeStopping(3000)}private suspend fun runWithDelayBeforeStopping(delayBeforeStopping: Long) { val server = ServerImpl(CoroutineScope(Dispatchers.Default)) // Inject external scope server.start() delay(delayBeforeStopping) // Use delay instead of Thread.sleep server.stop()}
Command to reproduce:
gt.sandbox.checkout.commit bed37c930bb1de4223cb \&& cd "${GT_SANDBOX_REPO}" \&& cmd.run.announce "./gradlew run --quiet"
Recorded output of command:
[elapsed: 51ms][🥇/tname:main/tid:1][coroutine:unnamed] --------------------------------------------------------------------------------[elapsed: 62ms][🥇/tname:main/tid:1][coroutine:unnamed] Example where the server is aborted prior to finishing:[elapsed: 65ms][🥇/tname:main/tid:1][coroutine:unnamed] Starting server[elapsed: 73ms][⓶/tname:DefaultDispatcher-worker-1/tid:20][coroutine:ServerWork-1] Running server work in thread: DefaultDispatcher-worker-1[elapsed: 74ms][⓷/tname:DefaultDispatcher-worker-2/tid:21][coroutine:ServerWork-2] Running additional server work in thread: DefaultDispatcher-worker-2[elapsed: 1084ms][🥇/tname:main/tid:1][coroutine:unnamed] Stopping server[elapsed: 1087ms][🥇/tname:main/tid:1][coroutine:unnamed] --------------------------------------------------------------------------------[elapsed: 1087ms][🥇/tname:main/tid:1][coroutine:unnamed] Example where the server has time to finish:[elapsed: 1087ms][🥇/tname:main/tid:1][coroutine:unnamed] Starting server[elapsed: 1088ms][⓶/tname:DefaultDispatcher-worker-1/tid:20][coroutine:ServerWork-1] Running server work in thread: DefaultDispatcher-worker-1[elapsed: 1088ms][⓷/tname:DefaultDispatcher-worker-2/tid:21][coroutine:ServerWork-2] Running additional server work in thread: DefaultDispatcher-worker-2[elapsed: 2594ms][⓷/tname:DefaultDispatcher-worker-2/tid:21][coroutine:ServerWork-2] ServerWork-2 completed[elapsed: 3093ms][⓷/tname:DefaultDispatcher-worker-2/tid:21][coroutine:ServerWork-1] ServerWork-1 completed[elapsed: 4089ms][🥇/tname:main/tid:1][coroutine:unnamed] Stopping server
import kotlinx.coroutines.*fun main() = runBlocking { val scope = CoroutineScope(Dispatchers.Default) val job = scope.launch { println("Job started") delay(1000) println("Job completed") } delay(500) // Wait for a while scope.cancel() // Cancel the scope // Attempt to launch a new job in the cancelled scope val newJob = scope.launch { println("New job started") delay(1000) println("New job completed") } newJob.invokeOnCompletion { exception -> if (exception is CancellationException) { println("New job was cancelled due to scope cancellation") } else if (exception != null) { println("New job completed with exception: $exception") } else { println("New job completed successfully") } } // Wait for all jobs to complete joinAll(job, newJob)}
Sample - 2
import kotlinx.coroutines.*fun main() = runBlocking { val scope = CoroutineScope(Dispatchers.Default) val job = scope.launch { println("Job started") delay(1000) println("Job completed") } delay(500) // Wait for a while scope.cancel() // Cancel the scope // Create a new scope and launch a new job val newScope = CoroutineScope(Dispatchers.Default) val newJob = newScope.launch { println("New job started") delay(1000) println("New job completed") } // Wait for all jobs to complete joinAll(job, newJob)}