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

jimmykiang
This test is broken right out of the box… — FAIL: TestAgent (7.82s) agent_test.go:77: Error Trace: agent_test.go:77 agent_test.go:...
New
yulkin
your book suggests to use Image.toByteData() to convert image to bytes, however I get the following error: "the getter ‘toByteData’ isn’t...
New
jamis
The following is cross-posted from the original Ray Tracer Challenge forum, from a post by garfieldnate. I’m cross-posting it so that the...
New
raul
Page 28: It implements io.ReaderAt on the store type. Sorry if it’s a dumb question but was the io.ReaderAt supposed to be io.ReadAt? ...
New
patoncrispy
I’m new to Rust and am using this book to learn more as well as to feed my interest in game dev. I’ve just finished the flappy dragon exa...
New
fynn
This is as much a suggestion as a question, as a note for others. Locally the SGP30 wasn’t available, so I ordered a SGP40. On page 53, ...
New
oaklandgit
Hi, I completed chapter 6 but am getting the following error when running: thread 'main' panicked at 'Failed to load texture: IoError(O...
New
adamwoolhether
Is there any place where we can discuss the solutions to some of the exercises? I can figure most of them out, but am having trouble with...
New
creminology
Skimming ahead, much of the following is explained in Chapter 3, but new readers (like me!) will hit a roadblock in Chapter 2 with their ...
New
dachristenson
I’ve got to the end of Ch. 11, and the app runs, with all tabs displaying what they should – at first. After switching around between St...
New

Other popular topics Top

PragmaticBookshelf
Stop developing web apps with yesterday’s tools. Today, developers are increasingly adopting Clojure as a web-development platform. See f...
New
PragmaticBookshelf
Machine learning can be intimidating, with its reliance on math and algorithms that most programmers don't encounter in their regular wor...
New
Exadra37
Please tell us what is your preferred monitor setup for programming(not gaming) and why you have chosen it. Does your monitor have eye p...
New
PragmaticBookshelf
From finance to artificial intelligence, genetic algorithms are a powerful tool with a wide array of applications. But you don't need an ...
New
PragmaticBookshelf
Rust is an exciting new programming language combining the power of C with memory safety, fearless concurrency, and productivity boosters...
New
AstonJ
I ended up cancelling my Moonlander order as I think it’s just going to be a bit too bulky for me. I think the Planck and the Preonic (o...
New
PragmaticBookshelf
Build highly interactive applications without ever leaving Elixir, the way the experts do. Let LiveView take care of performance, scalabi...
New
PragmaticBookshelf
Use WebRTC to build web applications that stream media and data in real time directly from one user to another, all in the browser. ...
New
PragmaticBookshelf
Escape callback hell and ship fast, clean code that reads as smoothly as it runs. Squash bugs and stamp out memory leaks with an intuitiv...
New
CommunityNews
Open-source implementation of the classic GTA engine now running directly in your browser. Experience the reVC technology demo on DOS.Zon...
New

Sub Categories: