Are there non-blocking suspend functions in the st...
# coroutines
r
Are there non-blocking suspend functions in the standard library that replace these blocking ones FileInputStream.read() FileOutputStream.write()?
đź‘€ 1
z
nope, but you can do something like
withContext(<http://Dispatchers.IO|Dispatchers.IO>) { read() }
r
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
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
it’s possible to create coroutine wrapper for nio, but there is no generic library. kotlinx.io and kotlinx.files are WIP
j
But
kotlinx-io
development seems to be stalled at the moment. Do you know if the project will resume anytime soon?
g
Yep, it's correct, kotlinx.io is it active development anymore, as I know, it probably will be reimplemented
l
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
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
You can customize the max number of threads to go beyond the default (which is 64)
r
Something like a slow loris attack could easily stall a server
Increasing the number of threads defeats the purpose of coroutines.
l
Not really
This is the max number
But I'd avoid having a server do local I/O for every client
r
Increasing the number of threads would just increase memory usage
l
Yes, but since your server apparently needs to do I/O on its hard drive…
r
This is also for network IO
l
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
Using a nonblocking read would be more efficient.
l
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
Also scaling threads would add more complexity to the code and could run out of memory
l
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
Do you have a link to something that goes into more detail?
g
Original question was about file is, not network. Also Okhttp is blocking io, just wrapped to thread pool
l
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
Sure, okhttp based on okio, which is blocking
l
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
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
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
I am using InputStream.read() for network IO so having a nonblocking suspend function would be ideal.
l
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
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