eg
GT-Sandbox-Snapshot: Example - 1, Cancelling using SupervisorJob
Code
package com.glassthought.sandbox
import gt.sandbox.util.output.Out
import 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
Cannot re-use scope
From Cannot Re Use Scope
Go to text ā
https://chatgpt.com/share/31be55da-2e7f-4dc8-9fc3-000384f58086
Sample - 1
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)
}
Backlinks