dhmitchell

dhmitchell

Kotlin Coroutine Confidence: asynchronous read file

In “gallery/v14/src/main/kotlin/com/example/gallery/GetImageFromFile.kt”

  • won’t the .use always call channel.close() on exit? if so, why do you need invokeOnCancellation? or does cancellation somehow avoid the finally in the use?
  • if I wanted to iterate through the file line by line, I presume I’d call readline rather than read and otherwise it’s roughly the same?

Marked As Solved

sam-cooper

sam-cooper

Author of Kotlin Coroutine Confidence

Yes, since the use() block wraps the entire call to suspendCancellableCoroutine(), it will always close the AsynchronousFileChannel when suspendCancellableCoroutine() exits for any reason. The problem is that without that invokeOnCancellation() block, suspendCancellableCoroutine() will not exit—at least, not until we’ve finished reading the entire file.

What we’re trying to do by adding invokeOnCancellation() is to ensure that we can stop the file operation before it finishes. When the coroutine is cancelled, Kotlin executes the invokeOnCancellation() block. Calling channel.close() inside the block is how we interrupt the ongoing file operation and cause it to end early.

That means there are two different ways the file can be closed:

  1. The read() operation ends on its own, either because it reached the end of the file or because it ran into an I/O error. The suspension point resumes, and the coroutine exits the use() block, closing the channel in the process.
  2. The user cancels the coroutine before read() is done. This triggers invokeOnCancellation(), which in turn calls channel.close(). This fires the read() operation’s failed() callback, allowing the coroutine to resume from its suspended state without waiting for the rest of the data. Again, it exits the use() block, but the file channel is already closed, so that’s a no-op.

I’ll see what I can do to make all this clearer in the book! Although it’s not something you’re likely to have to deal with often, I’d like to make sure it’s clear.

As for the second question, that’s a little trickier. The AsynchronousFileChannel just deals with raw byte data, and it doesn’t have any methods for working with text or line separators. Unfortunately that means there’s no readLine() function. You could write one of your own, but you’d need to include logic to buffer the data in chunks, inspect it for line separators, and so on.

In a real application, it’s likely that the more complete feature set of the java.io libraries will outweigh any asynchronous advantage from using java.nio. If I needed to read lines from a text file, I’d probably just use a good old fashioned Reader, and accept the minor cost of a blocked IO thread. In the book, I’m not intending to advocate for using AsynchronousFileChannel all over the place—it’s just meant as a handy example of a simple (ish) operation that we can use to illustrate asynchronous callbacks. Perhaps I’ll add a quick note to that effect in the text, too.

Phew! With any luck, I’ll find a way to say all this in the book using slightly fewer words. Thanks for asking these questions—they all help me to make the explanations in the book clearer.

Where Next?

Popular Pragmatic Bookshelf topics Top

johnp
Running the examples in chapter 5 c under pytest 5.4.1 causes an AttributeError: ‘module’ object has no attribute ‘config’. In particula...
New
simonpeter
When I try the command to create a pair of migration files I get an error. user=> (create-migration "guestbook") Execution error (Ill...
New
herminiotorres
Hi @Margaret , On page VII the book tells us the example and snippets will be all using Elixir version 1.11 But on page 3 almost the en...
New
AleksandrKudashkin
On the page xv there is an instruction to run bin/setup from the main folder. I downloaded the source code today (12/03/21) and can’t see...
New
swlaschin
The book has the same “Problem space/Solution space” diagram on page 18 as is on page 17. The correct Problem/Solution space diagrams ar...
New
leba0495
Hello! Thanks for the great book. I was attempting the Trie (chap 17) exercises and for number 4 the solution provided for the autocorre...
New
jgchristopher
“The ProductLive.Index template calls a helper function, live_component/3, that in turn calls on the modal component. ” Excerpt From: Br...
New
nicoatridge
Hi, I have just acquired Michael Fazio’s “Kotlin and Android Development” to learn about game programming for Android. I have a game in p...
New
andreheijstek
After running /bin/setup, the first error was: The foreman' command exists in these Ruby versions: That was easy to fix: gem install fore...
New
gorkaio
root_layout: {PentoWeb.LayoutView, :root}, This results in the following following error: no “root” html template defined for PentoWeb...
New

Other popular topics Top

New
New
AstonJ
This looks like a stunning keycap set :orange_heart: A LEGENDARY KEYBOARD LIVES ON When you bought an Apple Macintosh computer in the e...
New
Exadra37
I am asking for any distro that only has the bare-bones to be able to get a shell in the server and then just install the packages as we ...
New
rustkas
Intensively researching Erlang books and additional resources on it, I have found that the topic of using Regular Expressions is either c...
New
Maartz
Hi folks, I don’t know if I saw this here but, here’s a new programming language, called Roc Reminds me a bit of Elm and thus Haskell. ...
New
AstonJ
Was just curious to see if any were around, found this one: I got 51/100: Not sure if it was meant to buy I am sure at times the b...
New
RobertRichards
Hair Salon Games for Girls Fun Girls Hair Saloon game is mainly developed for kids. This game allows users to select virtual avatars to ...
New
mindriot
Ok, well here are some thoughts and opinions on some of the ergonomic keyboards I have, I guess like mini review of each that I use enoug...
New
PragmaticBookshelf
Use advanced functional programming principles, practical Domain-Driven Design techniques, and production-ready Elixir code to build scal...
New

Sub Categories: