Hi there, how am i supposed to launch coroutines i...
# ktor
t
Hi there, how am i supposed to launch coroutines in a request handler? I want to instantly respond to the client and handle the request in the background using a coroutine. I tried to do it this way and it also works, but when i extract the request handler into an extra function, then intellij gives me a justified warning. No warning:
Copy code
get("/test") {
    launch {
        // do something
    }

    call.respond("Success")
}
Warning
Ambiguous coroutineContext due to CoroutineScope receiver of suspend function
when using:
Copy code
suspend fun PipelineContext<Unit, ApplicationCall>.handleTest() {
    launch {
        // do something
    }

    call.respond("Success")
}

get("/test") {
    handleTest()
}
How am i supposed to do this?
h
PipelineContext already extend CoroutineScope. You should either use
suspend fun handleTest(): String { return "Success"}
or
Copy code
fun PipelineContext.handleTest() {
call.respond("Success")
}
t
I am afraid that the PipelineContext will get cancelled and thus the coroutine that i launched using it will stop and not complete the task. Can this be the case?
And i need to be the function to suspend as i am calling other suspending functions in it.
d
This may be a case where it's appropriate to use GlobalScope; especially if you launch a parent supervisor Job inside GlobalScope first that groups together all such background tasks?
t
What do you mean by parent supervisor job?
j
What I did to handle a request and then send a socket update to other clients without blocking the response, is to launch the work in another scope. If you just use
launch
, you use the pipelines' scope. You should just define another scope (
CoroutineScope(Dispatchers.Default)
for example) and this worked like a charm!
t
Is there something bad about using the pipeline’s scope actually?
j
I am not sure, but I can imagine the pipeline scope to be scoped to the actual request/response. Triggering other (long running) work that falls outside of the request/response scope feels better to handle in a specific scope for that task
t
Do you have an example that you can share with me?
j
I'm not sure when the scope gets cancelled, I can imagine it to be terminated after the response been made successfully but I guess ktor professionals might know the answer to that
t
It seems to keep existing even after the response finished successfully. At least i tried it out and id did…
a
The Ktor doesn't cancel jobs for routes handlers so your background job won't be canceled too. Also, you can make your job independent by creating a new one for the context of `launch`:
Copy code
launch(coroutineContext + Job()) {
    repeat(10000) {
        println("Executing background task $it.")
        delay(1000)
    }
}
t
Is it written somewhere in the documentation that ktor doesn’t cancel the jobs?
a
I don't think so.
t
okay, thanks. What exactly is the benefit of using
+ Job()
. As the jobs will not get cancelled anyways it should not be required, shouldn’t it?
h
But you don't want to cancel Ktor`s job if your job fails :)
😅 1
t
True story, learned something again. Thanks!