comprehensive-rust icon indicating copy to clipboard operation
comprehensive-rust copied to clipboard

Make chat-client reads cancellation safe

Open mauvealerts opened this issue 1 year ago • 5 comments

AsyncBufReadExt::read_line() isn't cancellation safe. In practice, this doesn't matter much because we expect the client to be run from a terminal, which buffers by lines anyway. Since using the cancellation-safe approach is so simple, it seems worth fixing.

Related: This is a pretty common mistake, particularly with select!. I'm debating between adding (possibly in a separate PR):

  • a speaker note on the select! slide
  • a separate slide (in "Pitfalls") about cancellation (e.g. could mention explicit signaling)

@djmitche @rbehjati thoughts? (n.b. I'm OOO, back on June 6)

mauvealerts avatar May 28 '23 00:05 mauvealerts

  • a speaker note on the select! slide
  • a separate slide (in "Pitfalls") about cancellation (e.g. could mention explicit signaling)

I would love to see an explanation for this — I see the diff here, but it's not clear to me how this fixes a problem :smile: You can certainly be done in a followup PR.

mgeisler avatar May 28 '23 15:05 mgeisler

I would love to see an explanation for this — I see the diff here, but it's not clear to me how this fixes a problem 😄 You can certainly be done in a followup PR.

I wrote a quick draft in #716 .

For the purposes of this PR, the potential data loss is due to the combination of:

  • select! drops the futures of unmatched branches, and
  • read_line advances the reader but doesn't necessarily expose data in the buffer until it reads a newline.

There are a few options, but using the lines() method is the simplest one I know of.

mauvealerts avatar May 29 '23 03:05 mauvealerts

@mauvealerts Can you also update the list of required APIs in the description of the exercise?

In particular this line: https://github.com/google/comprehensive-rust/blob/c0138a424fdd4ebf108544363791295a067ce93b/src/exercises/concurrency/chat-app.md?plain=1#L32

Instead of BufReader::read_line(), we want the API for Lines::next_line().

rbehjati avatar Jun 05 '23 12:06 rbehjati

I included links to both AsyncBufReadExt::lines() and Lines::next_line() as a single list-item, since they're so closely related. If it's too cluttered, I agree Lines::next_line() is more relevant.

mauvealerts avatar Jun 05 '23 15:06 mauvealerts

I included links to both AsyncBufReadExt::lines() and Lines::next_line() as a single list-item, since they're so closely related. If it's too cluttered, I agree Lines::next_line() is more relevant.

Thanks. I think it is better to keep just Lines::next_line(), to be consistent with the rest of the listed APIs. We have not listed all the APIs, but only the ones required for completing the code. I assume that people will be able to easily find the API for the given code.

rbehjati avatar Jun 05 '23 16:06 rbehjati

Thanks for this, I think it's ready to merge now?

mgeisler avatar Jun 09 '23 13:06 mgeisler

Yes, this should be ready to merge AFAIK.

mauvealerts avatar Jun 09 '23 13:06 mauvealerts

Yes, this should be ready to merge AFAIK.

In it goes! :tada:

mgeisler avatar Jun 09 '23 14:06 mgeisler