https://kotlinlang.org logo
#coroutines
Title
# coroutines
r

Rob

01/06/2021, 12:34 AM
Are there non-blocking suspend functions in the standard library that replace these blocking ones FileInputStream.read() FileOutputStream.write()?
👀 1
z

Zach Klippenstein (he/him) [MOD]

01/06/2021, 1:59 AM
nope, but you can do something like
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { read() }
r

Rob

01/06/2021, 3:04 AM
That's what I'm already doing but if there are a lot of concurrent reads then all the threads could still get saturated.
I don't have much experience wit nio but maybe it's possible to wrap those methods.
z

Zach Klippenstein (he/him) [MOD]

01/06/2021, 3:43 AM
Some libraries, like ktor, i think support truly asynchronous IO using stuff like netty, but idk if there’s a more general wrapper around nio.
g

gildor

01/06/2021, 6:44 AM
it’s possible to create coroutine wrapper for nio, but there is no generic library. kotlinx.io and kotlinx.files are WIP
j

Joffrey

01/06/2021, 10:08 AM
But
kotlinx-io
development seems to be stalled at the moment. Do you know if the project will resume anytime soon?
g

gildor

01/06/2021, 1:33 PM
Yep, it's correct, kotlinx.io is it active development anymore, as I know, it probably will be reimplemented
l

louiscad

01/06/2021, 2:28 PM
There was no perf gain with NIO channels because most OSes don't have a proper non blocking I/O under the hood that is actually more performant than the blocking one. So
<http://Dispatchers.IO|Dispatchers.IO> { }
is good enough.
r

Rob

01/06/2021, 2:32 PM
I don’t believe that without some reference. If I have a server that’s reading on 100 client sockets where all the threads in io are blocked on read because the connection is stalled, the other sockets with data will not get processed.
l

louiscad

01/06/2021, 2:33 PM
You can customize the max number of threads to go beyond the default (which is 64)
r

Rob

01/06/2021, 2:33 PM
Something like a slow loris attack could easily stall a server
Increasing the number of threads defeats the purpose of coroutines.
l

louiscad

01/06/2021, 2:34 PM
Not really
This is the max number
But I'd avoid having a server do local I/O for every client
r

Rob

01/06/2021, 2:35 PM
Increasing the number of threads would just increase memory usage
l

louiscad

01/06/2021, 2:35 PM
Yes, but since your server apparently needs to do I/O on its hard drive…
r

Rob

01/06/2021, 2:36 PM
This is also for network IO
l

louiscad

01/06/2021, 2:38 PM
For these many local I/O operations, you can also use a custom dispatcher that scales up to a limit and back down after a while or shorter than a while. That limit might be tuned to the hardware capabilities to avoid having threads actually blocked just waiting.
r

Rob

01/06/2021, 2:38 PM
Using a nonblocking read would be more efficient.
l

louiscad

01/06/2021, 2:38 PM
Network I/O should not be done on
<http://Dispatchers.IO|Dispatchers.IO>
but with coroutines library like ktor client or OkHttp (or both), or Retrofit
r

Rob

01/06/2021, 2:40 PM
Also scaling threads would add more complexity to the code and could run out of memory
l

louiscad

01/06/2021, 2:40 PM
For local I/O, I already told you that it's not the case (but I think Darwin based OSes have an async file I/O API that is actually performant, unlike other Unix/Linux OSses so far)
Also scaling threads would add more complexity to the code and could run out of memory
Not really, the JVM already has facilities to do it with just a few configuration parameters
r

Rob

01/06/2021, 2:41 PM
Do you have a link to something that goes into more detail?
g

gildor

01/06/2021, 2:42 PM
Original question was about file is, not network. Also Okhttp is blocking io, just wrapped to thread pool
l

louiscad

01/06/2021, 2:42 PM
Is OkHttp blocking while waiting for the server response (other than DNS server)?
@Rob See this thread where the now Kotlin's lead replied: https://kotlinlang.slack.com/archives/C1CFAFJSK/p1573832848251800
g

gildor

01/06/2021, 2:43 PM
Sure, okhttp based on okio, which is blocking
l

louiscad

01/06/2021, 2:45 PM
I was thinking maybe there was a callback to wait for the response stream, and only block while writing (request) and reading (response incoming) to it, but I think you're right that even while the client waits, a thread from a private pool is blocked.
r

Rob

01/06/2021, 2:46 PM
Sorry, my original question was with file io and then I started thinking about network io. https://kotlinlang.slack.com/archives/C1CFAFJSK/p1574002124304700?thread_ts=1573832848.251800&amp;cid=C1CFAFJSK
Being a old C hacker, the socket api for network and file is the same and I thought it the API would be the same in Java
l

louiscad

01/06/2021, 2:48 PM
Well, there's a java API for network that works for file urls too, but I don't use it because I use ktor or OkHttp for non file I/O
r

Rob

01/06/2021, 3:54 PM
I am using InputStream.read() for network IO so having a nonblocking suspend function would be ideal.
l

louiscad

01/06/2021, 3:58 PM
ktor with the CIO or any other async engine would work. Or you can search for java async network and do it on your own with suspendCancellableCoroutine (but might get tricky to do if you need http2+, at which point existing solutions like ktor client are probably better suited)
r

Rob

01/06/2021, 4:00 PM
This is for an Android client where I'm using OkHttp to download a file. Normally I would use Retrofit but these are several large files downloaded concurrently.
I needed to show download progress for several files so I created a Flow
57 Views