Location (URL)
https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_end
https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_string
https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all_vectored
Summary
std::io::{Read, Write} convenience methods that have semantics of doing the operation "fully", such as read_to_end or write_all, have confusing / surprising interactions with sockets that might return std::io::ErrorKind::WouldBlock or std::io::ErrorKind::TimedOut: the operation – on the contrary to the main semantics of the method – might only happen partially on an error. With "retryable" errors, one might expect to be able to retry the operation, but retrying will produce duplicate writes and broken behaviour.
One might expect this to happen after setting the socket to a non-blocking / async mode. However, for example, when setting timeouts with set_read_timeout or set_write_timeout, this might be far more surprising, especially given that the error that results is platform-specific.
I think that the docs would do very well to add a mention about this behaviour in the Usage Notes sectors of the affected methods. Currently, to be able to understand the behaviour of these operations, one must have a clear understanding how they are implemented internally, i.e. in their current form, they are broken abstractions.
A similar issue was closed by the poster before, because it got some pushback about the semantics being clear enough with "combining those two facts (about the method implementation and the socket error codes)" from the documentation about the methods in question. But I know that Rust docs strive for doing better in case of surprising semantics. I think this is an actionable and reasonable thing to fix in the docs, so I'm reopening this as a new issue. I'm willing to contribute the fix to the stdlib docs.
Location (URL)
https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_end
https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_string
https://doc.rust-lang.org/std/io/trait.Read.html#method.read_exact
https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all
https://doc.rust-lang.org/std/io/trait.Write.html#method.write_all_vectored
Summary
std::io::{Read, Write}convenience methods that have semantics of doing the operation "fully", such as read_to_end or write_all, have confusing / surprising interactions with sockets that might returnstd::io::ErrorKind::WouldBlockorstd::io::ErrorKind::TimedOut: the operation – on the contrary to the main semantics of the method – might only happen partially on an error. With "retryable" errors, one might expect to be able to retry the operation, but retrying will produce duplicate writes and broken behaviour.One might expect this to happen after setting the socket to a non-blocking / async mode. However, for example, when setting timeouts with set_read_timeout or set_write_timeout, this might be far more surprising, especially given that the error that results is platform-specific.
I think that the docs would do very well to add a mention about this behaviour in the Usage Notes sectors of the affected methods. Currently, to be able to understand the behaviour of these operations, one must have a clear understanding how they are implemented internally, i.e. in their current form, they are broken abstractions.
A similar issue was closed by the poster before, because it got some pushback about the semantics being clear enough with "combining those two facts (about the method implementation and the socket error codes)" from the documentation about the methods in question. But I know that Rust docs strive for doing better in case of surprising semantics. I think this is an actionable and reasonable thing to fix in the docs, so I'm reopening this as a new issue. I'm willing to contribute the fix to the stdlib docs.