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

nilTheDev

10/28/2021, 10:51 AM
How coroutines work in ktor? I was checking out the samples and in the async sample I found that suspend functions are being called without any coroutine scopes.
Copy code
get("/{...}") {
            val startTime = System.currentTimeMillis()
            
            // this is a suspend function
            call.respondHandlingLongCalculation(random, delayProvider, startTime)
        }
In this code,
call.respondHandlingLongCalculation(...)
is a suspend function and it is called without using any
launch
block. It seems that there is always a coroutine scope lying around in the ktor application. Q1. How can I use coroutines in a ktor application? If there is an implicit scope then what are the best practices to use it? Is there any guidelines? Q2. The scope of this question is little bit broad. How exactly a ktor server handle client connections? Does it launch a whole new instance of the application in a coroutine and it lives until the connection is closed? If not then how it manages concurrent connections? Let's say user A and user B connected to the server simultaneously. Though servers should be as stateless as possible but suppose I made a list of something for serving user A. Something like that,
Copy code
// this is a global variable
var list: List<Int>? = null

fun ... (){
    get("..."){
        call.respond(list)
    }
}
Is there any chance that user A's data can also get served to user B if they hit the same endpoint?
k

Kamil Kalisz

10/28/2021, 11:42 AM
1. Your get/post handler lambda is already suspend function and is invoked in coroutine context by KTOR. (So you have that support out of the box) 2. There is one instance of application, new coroutine is invoked for each connection, If you do global variable as in example it will be visible for everyone, so yes data will be shared
n

nilTheDev

10/28/2021, 12:29 PM
Got it thanks. Q1. But I was wondering what if I needed to use coroutines somewhere else in my application e.g some class that access database, which scope I should use? Would it be something that Ktor provides or I can create a normal one on my own? Q2. And as you said the global variables will be shared, then if I store it inside the argument lambda of some
get
or
post
endpoint then it won't be shared right? So, even if I invoke an function from
get
that has local variables it wouldn't be shared too. Basically I am trying to understand each coroutines, fired for each connection, will maintain its own stack or not. I'm not sure whether the second question make sense.
k

Kamil Kalisz

10/28/2021, 1:30 PM
1. In most cases using coroutine provided by ktor is enough . Of course you can use different dispatchers etc., but still everything related to request that you are handling should be done/handled in coroutine created by ktor. You may need launching coroutines from some periodic operations that should be done independent of requests, For example scrapping data from external services once per 15 minutes. But in that case you can spawn your own coroutine outside routing block 2. You are right local variables inside get/post block will not be shared between calls. And Yes each connection will get own stack in terms of get/post block
🔥 1
n

nilTheDev

10/28/2021, 1:37 PM
Super helpful. Thanks!
20 Views