Hi all, i have a question on coroutines and Dispat...
# server
l
Hi all, i have a question on coroutines and Dispatchers. Our microservice use sync (non async) pooled Apache http Client with 40 connections when requesting something from 3rd party API - call is wrapped inside withContext (Dispatchers.IO) {the_call_here} Question1: since this is sync http Client, does underlying thread gets fully blocked during the entire request? Question2: since javadoc of Dispatchers.IO mentions the thread pool is shared with Dispatchers. Default, does that mean sometimes rest of out app coroutines gets effectively blocked when we have high load and all of our 8 threads from Dispatchers. Default are waiting for Http calls to finish?
s
1. Yes, if you use the blocking version of the HTTP client, the thread is blocked while you make the request and wait for the response. 2. No, it'll create additional threads for the blocking calls, and will keep sufficient threads in reserve for your non-IO coroutines.
l
About2: I'm asking if other places of out application, which schedule their coroutines on Default Imagine scenario: if threads from 1-8 from Dispatchers.Default are all blocked on executing IO requests (because Dispatchers.IO shares the thread pool) and now if some non-IO part of microservice tries to launch coroutine on Dispatchers.Default, - then my understanding is that this coroutine will need to wait because all 8 threads are blocked AND Dispatchers.Default will not create new threads Does that makes sense?
s
You're right that the thread pool is shared, but in fact it can and will create new threads when needed
If you have eight cores, eight threads are always reserved for the default dispatcher. If one of those threads is taken over by the IO dispatcher, a new thread will be created to preserve the desired total of reserved threads 👍
❤️ 1
l
That sounds very reasonable, do you know any documentation that lists this design?
s
Not exactly 😞. There are some detailed doc-comments in the source code, e.g. here. But I can't find a public-facing explanation of how the shared thread pool works on the JVM.
h
A word of advice if you want to avoid thread exhaustion issues with coroutines: never use orphaned blocks: use
runBlocking
at the beginning of your request handler and avoid using it again inside. Follow Google’s advice for Android on the Server Side as well: do not switch to the IO dispatcher too early. Only the function that actually performs the I/O operation should be responsible for changing to the io context.