Skip to content
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

proposal: io: accept ErrShortWrite if Write reports no error #49474

Closed
changkun opened this issue Nov 9, 2021 · 9 comments
Closed

proposal: io: accept ErrShortWrite if Write reports no error #49474

changkun opened this issue Nov 9, 2021 · 9 comments

Comments

@changkun
Copy link
Member

changkun commented Nov 9, 2021

Currently, when a writer Writes non-zero bytes content and also does not report an error,
the io.Copy will report io.ErrShortWrite. For example, this test will fail:

https://play.golang.org/p/ixBBi5pm6mh

If an incomplete writer writes incomplete content but postpones the task to the next write, it would be better to call Write again until all read has been written, so that the above test can pass.

@gopherbot gopherbot added this to the Proposal milestone Nov 9, 2021
@gopherbot
Copy link

Change https://golang.org/cl/362514 mentions this issue: io: accept ErrShortWrite if Write reports no error

@changkun
Copy link
Member Author

changkun commented Nov 9, 2021

cc @griesemer @ianlancetaylor @bradfitz

CL 362514 is also sent for the proposed change.

@nightlyone
Copy link
Contributor

I think the current feedback from io.Copy is very useful to re-adjust your copy buffers.

That is also a sane way to detect whether you missed write buffering.

If your read and write chunk sizes are not aligned you need to wrap it in a bufio.Writer and bufio.Reader I think. Until now I thought that is exactly their purpose.

If the current bufio package doesn't help your use case I would like to hear more about it.

@bcmills
Copy link
Contributor

bcmills commented Nov 9, 2021

If an incomplete writer writes incomplete content but postpones the task to the next write

The io.Writer interface does not allow a valid Writer to postpone anything to the next write, and existing callers that accept an io.Writer are often not written with short writes in mind. This would be a backward-incompatible change.

@changkun
Copy link
Member Author

changkun commented Nov 9, 2021

The io.Writer interface does not allow a valid Writer to postpone anything to the next write, and existing callers that accept an io.Writer are often not written with short writes in mind.

Interesting, sorry that didn't read through the requirement of io.Writer. If so then this proposal also implies relaxing the requirement of io.Writer. Otherwise, what's the historical reason to have such a requirement?

This would be a backward-incompatible change.

Why is it backward-incompatible? The requirement is only relaxed, isn't it?

@neild
Copy link
Contributor

neild commented Nov 9, 2021

Why is it backward-incompatible? The requirement is only relaxed, isn't it?

Because relaxing the requirement breaks approximately every piece of code which calls Write today, assuming that it will never postpone anything to the next write. For example, relaxing this requirement breaks io.Copy.

@changkun
Copy link
Member Author

changkun commented Nov 9, 2021

Because relaxing the requirement breaks approximately every piece of code which calls Write today, assuming that it will never postpone anything to the next write. For example, relaxing this requirement breaks io.Copy.

I assume this must be a misunderstanding. If all existing Write guarantees a complete write, then relax the requirement does not impact any existing code because io.Copy can still proceed with the next Read directly, after the read buffer is completely written. See the changes in the CL 362514

@neild
Copy link
Contributor

neild commented Nov 9, 2021

See the changes in the CL 362514

Yes, exactly: You need to change io.Copy to make it work with an io.Writer which can return a short write.

If the io.Writer contract were changed in this way, a similar change would need to be made to every piece of code that calls Write. Thus, this would be a backwards-incompatible change.

@ianlancetaylor
Copy link
Contributor

If an incomplete writer writes incomplete content but postpones the task to the next write, it would be better to call Write again until all read has been written, so that the above test can pass.

Any writer that wants that behavior is required to do its own buffering. That is part of the contract of io.Writer, and as discussed above we can't change that now. Closing this issue. Sorry.

@golang golang locked and limited conversation to collaborators Nov 9, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants