`ByteReadChannel.copyTo(WritableByteChannel)` is d...
# ktor
u
ByteReadChannel.copyTo(WritableByteChannel)
is documented to only work with blocking NIO channels
d
Where is that used? Kotlinx-io has some classes similar in name, but not from the java package. And those are marked as suspend
u
I used it in my code in order to write the
ByteReadChannel
created via HttpResponse.content to a file channel
d
let me check
u
Copy code
val networkChannel = httpResponse.content
FileChannel.open(tmpPath,
                StandardOpenOption.WRITE,
                StandardOpenOption.TRUNCATE_EXISTING).use { targetChannel ->
            networkChannel.copyTo(targetChannel)
        }
And I wonder if this is simply the wrong approach
copyTo
comes from
kotlinx.coroutines.experimental.io.jvm.nio. WritingKt
d
what you want is to copy a
ByteReadChannel
from kotlinx-io into a https://docs.oracle.com/javase/7/docs/api/java/nio/channels/AsynchronousFileChannel.html ?
u
I guess, that would do the trick, yes
d
It end using a thread pool in any case
u
I also suppose HttpResponse.content creates a non-blocking channel. is this true?
d
thought they might change in the future
yeah, sockets should be fully asynchronous
u
files are not?
d
An AsynchronousFileChannel is associated with a thread pool to which tasks are submitted to handle I/O events and dispatch to completion handlers that consume the results of I/O operations on the channel. The completion handler for an I/O operation initiated on a channel is guaranteed to be invoked by one of the threads in the thread pool (This ensures that the completion handler is run by a thread with the expected identity). Where an I/O operation completes immediately, and the initiating thread is itself a thread in the thread pool, then the completion handler may be invoked directly by the initiating thread. When an AsynchronousFileChannel is created without specifying a thread pool then the channel is associated with a system-dependent default thread pool that may be shared with other channels. The default thread pool is configured by the system properties defined by the AsynchronousChannelGroup class.
u
but the thread pool only handles 'io events'. does not sound blocking to me.
d
well your main thread not, but you can also dispatch the copy while using a FileChannel
u
I mean, your quote says
associated with a thread pool to which tasks are submitted to handle I/O events
and `This ensures that the completion handler is run by a thread with the expected identity`` both sound non-blocking to me. It does not read as if the actual IO would be performed in the thread pool.
d
aha
well, what you can do is to create a copyTo function working with AsynchronousFileChannel
by reading chunks from the ByteReadChannel, and writing to the AsynchronousFileChannel
you can create a suspend extension method for handling AsynchronousFileChannel methods using completion handlers
I can help you if you have troubles doing that, and put a sample in the ktor-samples repo
u
I was just wondering if something along those lines was already there as ktor's idea is non-blocking coroutines .
Shouldn't that go in the ktor client lib? EDIT: into kotlinx-io
d
maybe eventually, but I think there is no work on filesystem yet for kotlinx-io (unless I missed something)
u
thanks for your support. I'll see if i find the time and get back to you.
👍 1
it is probably not filesystem related. My first impression is, an implementation on `AsynchronousChannel`would also be possible
d
Yeah, for sure, I also think it is possible. But maybe not done yet (I have still to check in detail). If that’s the case, the first step is to create a working snippet, then a PR 🙂. I usually put those in ktor-samples, and change the code once they are available in the main codebase (so people can use that functionality in the meantime)
u
Ok. Thanks
c
Note that
AsynchronousChannel
is running a blocking operations on a separate pool in fact. This is because files are always blocking due to underlying native implementation except Windows.
r
Wait, Windows does something better??