Hi The below code works but the next block does no...
# coroutines
m
Hi The below code works but the next block does not work. please advise why.
Copy code
var resultMap = mutableMap 
withContext(Dispatchers.IO) {
    val job = async {
         try {
            //some jdbc call
            result['data'] = //jdbc result
         } catch (ex: Exception){
             result['error'] = ex
         }
    } 
    job.await()
}
bock that fails:
Copy code
var resultMap = mutableMap 
    val job = async(Dispatchers.IO) {
         try {
            //some jdbc call
            result['data'] = //jdbc result
         } catch (ex: Exception){
             result['error'] = ex
         }
    } 
    job.await()
s
It's hard to say what the problem is from this code snippet. Maybe you could say a bit more about what you're trying to do and what problem you're seeing? Calling
await
immediately after starting a new coroutine is an unusual thing to do and suggests you might not need the
async
block at all.
👍🏾 1
👍 1
m
okay, I am trying this code in a suspended func of a ktor app. The second block does not compile at all. Aside, looking at the first block, is it a correct approach to run the JDBC call using asyc coroutine with Dispatchers.IO as the context?
s
Ah, okay, I understand the problem. The second block doesn't compile because you don't have a coroutine scope. The
withContext
function creates a coroutine scope, which allows you to launch new coroutines via
async
and
launch
. However, in this case, you don't need an additional coroutine, because you only have one task to perform. You can run your code directly inside the
withContext
block, without
async
. Starting additional coroutines here would only be necessary if you want to multitask, e.g. making two simultaneous network calls.
👍🏾 1
👍 1
m
will the use Of
withContext
alone take care of doing non blocked IO for the jdbc call? How do I know if the thread is blocked or not?
s
Yes,
withContext(<http://Dispatchers.IO|Dispatchers.IO>)
will take care of moving the blocking IO onto the IO dispatcher so it doesn't block the calling thread. It's a suspending function, so it doesn't block its caller.
m
Noted. Thank you very much. Does it mean some other thread in the Dispatchers.IO Threadpool gets blocked during the network call? Will there be a difference in performance if I use Java21 virtual threadpool instead of Dispatchers.IO
s
Yes, the network call will block a thread belonging to the IO dispatcher. But these threads already exist, and are there to be used for this purpose, so using some other thread instead probably won't help. In fact, the IO dispatcher is optimised to minimise thread-switching when swapping to it from the default dispatcher, and performance could actually be worse without that optimisation. In future I expect we will see a version of the IO dispatcher that is built on top of Java 21 virtual threads; until then, I wouldn't worry.
👍🏾 1
m
Got it. Thanks a lot