tokio-rs / tokio

A runtime for writing reliable asynchronous applications with Rust. Provides I/O, networking, scheduling, timers, ...
https://tokio.rs
MIT License
26.78k stars 2.47k forks source link

`AsyncReadExt::read_exact` should retry ErrorKind::Interrupted #6162

Open calmofthestorm opened 11 months ago

calmofthestorm commented 11 months ago

Version 1.34.0

Platform Linux alder 6.1.0-9-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.27-1 (2023-05-08) x86_64 GNU/Linux

Description

tokio::io::ReadAsync::read_exact will propagate an std::io::ErrorKind::Interrupted error back to the caller, rather than retrying like its counterpart std::io::Read::read_exact.

I speculate that this is because Interrupted does not commonly come up from non-blocking I/O implementations the way it does for blocking.This is technically working as documented, but I don't think it's working as intended, since implementations of AsyncRead could reasonably assume it is acceptable to return Interrupted if there were a use case for it, and client code is unlikely to handle it since doing so in the std case is unnecessary, and arguably core functionality of read_exact, principle of least surprise, etc.

https://gist.github.com/calmofthestorm/0c95c6f23ed9014238c0d722ee7d97c2 shows how a simple [Async]Read implementation that spuriously returns Interrupted works with std read_exact but not the Tokio equivalent.

rcastill commented 9 months ago

I think the same goes for the return type. If it succeeds, it always returns Ok(me.buf.capacity()). In that case, it's better to return io::Result<()> like its counterpart.

Darksonn commented 9 months ago

@rcastill The return type cannot be changed.

rcastill commented 9 months ago

I realize that. Maybe a comment in the docs?