-
Notifications
You must be signed in to change notification settings - Fork 13k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
non-blocking stream & io::Write::write_all method are not compatible and result in unexpected user behavior #115483
Comments
The documentation for
And the documentation for
Combining those two facts means that write_all will abort due to an error if the socket would have to block. The correct pattern is:
|
If you want to do non-blocking io, there is great crates in the ecosystem that offer it really well, e.g. tokio. |
if you read the documentation verbatim I suggests that a retry of write_all is possible after receiving a WouldBlock error. However, it is not possible to recover from this error by trying again given that the session has been corrupted and with a half completed write so trying to write_all again will just continue to corrupt an already corrupted sequence of bytes the receiver expects. Either method shall be documented to say it is not possible to use write_all with non-blocking to transfer a sequence of bytes over a network without a possibility of corrupting data being sent. |
Certainly. But that means this combination of methods isn't usable. The docs don't have to spell out every possible combination of uses on all methods. If one API demands something of you and that can't be fulfilled by using A then perhaps you have to use B instead. That is the kind of reasoning that a human programmer has to do all the time or that more complex example programs / tutorials are useful for. We can document this anyway. But as general expectation you shouldn't assume that every method documents its interaction with every other method. |
Non-blocking stream being another type would really help in lifting the burden, IMHO. This ship has sailed, though. |
Yes. But this isn't specific to non-blocking IO anyway. Any time you need to recover from partial writes or need finer control over the block sizes you'll want to use |
Location
This is a continuation of #115451
Summary
The following block of code has unexpected behavior as it will likely not write_all bytes to the stream but there is no way for user to know who many if any where written.
Perhaps the trait should take a mut buf: &[u8] so that the user can check? In either case it is a very hard issue to troubleshot as it fails only on some platforms and under certain conditions yet there is no mention anywhere that nonblocking sockets and io::Write ::write_all method are not compatible.
The text was updated successfully, but these errors were encountered: