https://kotlinlang.org logo
#ktor
Title
# ktor
t

Tobias Marschall

10/23/2021, 5:47 PM
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

hfhbd

10/23/2021, 10:59 PM
PipelineContext already extend CoroutineScope. You should either use
suspend fun handleTest(): String { return "Success"}
or
Copy code
fun PipelineContext.handleTest() {
call.respond("Success")
}
t

Tobias Marschall

10/24/2021, 10:24 AM
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

darkmoon_uk

10/24/2021, 1:45 PM
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

Tobias Marschall

10/24/2021, 2:47 PM
What do you mean by parent supervisor job?
j

Joost Klitsie

10/24/2021, 6:49 PM
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

Tobias Marschall

10/24/2021, 6:51 PM
Is there something bad about using the pipeline’s scope actually?
j

Joost Klitsie

10/24/2021, 6:54 PM
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

Tobias Marschall

10/24/2021, 6:56 PM
Do you have an example that you can share with me?
j

Joost Klitsie

10/24/2021, 6:56 PM
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

Tobias Marschall

10/24/2021, 6:56 PM
It seems to keep existing even after the response finished successfully. At least i tried it out and id did…
a

Aleksei Tirman [JB]

10/25/2021, 8:21 AM
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

Tobias Marschall

10/25/2021, 1:43 PM
Is it written somewhere in the documentation that ktor doesn’t cancel the jobs?
a

Aleksei Tirman [JB]

10/25/2021, 5:53 PM
I don't think so.
t

Tobias Marschall

10/25/2021, 7:21 PM
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

hfhbd

10/26/2021, 9:07 AM
But you don't want to cancel Ktor`s job if your job fails :)
😅 1
t

Tobias Marschall

11/01/2021, 5:29 PM
True story, learned something again. Thanks!