-
Notifications
You must be signed in to change notification settings - Fork 164
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
GzDecoder
eager reading in the constructor blocks IO
#368
Comments
You have a good point that parsing the header in the constructor is not idiomatic. But a change would be backwards-incompatible. If the inner reader is blocking then a caller can expect that, after a successful |
In this case calling |
True. The |
I feel whether I feel it is probably ok to go ahead and make |
I'd be interested in understanding how the current behaviour of eagerly reading the header came to be. Without any knowledge on how this came to be, I would tend to make this API more conventional, reporting errors when they occour and doing work only when needed, but reflect that, along with failure modes, in the signature of each method. Making any change to signatures would probably break the symmetry among the different implementations, which makes it even more prohibitive and brings me back to trying to understand why this way of handling things was desirable in the first place, as I am clearly having a knowledge gap :/. |
Looking at some older code the reason for parsing the header seems to be that all the formats supported by In #185 support for |
Thanks for the detective-work and the additional explanation. Regarding the header being an inconvenience to be skippedI could imagine that it was simply easiest to strip the header off the first chance one gets, disregarding that doing IO in the constructor might be unexpected or even problematic under circumstances. To me it seems that there is no reason we'd know that would rate the current behaviour higher (to make it worth keeping) in the face of the problem its causing. To fix it, one would have to lazily parse the header during the first The behaviour of Trying to scrutinise the paragraph above, one might say previously one could use This looks like we should go ahead and make this type/these types lazy - what do you think? |
If the state is The
Before making these technically backwards-incompatible changes (even if they are relied on by very few, if any, people) I suggest that there is a 1.0.27 release with the changes to The changes suggested for this issue can then go into a 1.1.0 release so that if anyone does rely on the previous behaviour they can pin to 1.0 and we keep open the possibility of back-porting fixes to 1.0 if there is demand. |
Thanks a lot for the assessment, it makes sense to me and I am looking forward to seeing it through. The new release is in preparation and can happen once my PR was merged. |
Currently the
GzDecoder
new
method eagerly attempts to read the header information in the constructor. It hasmatch
statements for if the io should be non-blocking, but in general this will never happen. I think it would be more proper to follow the usual pattern of constructors in Rust not doing work by trying to read the underlying stream, and instead lazily determine the state when a read is requested.The case where this eager reading behavior is a problem is when there are multiple fifo stream being initialized. The first decoder created will block on trying to read from the underlying stream before any work as been done, preventing the rest of the application from working. I don't think it is technically incorrect, but in general Rust prefers being lazy with computation especially when it has side effects.
The current workaround that I have to use to avoid generating
read
syscalls during construction is pretty hacky:The text was updated successfully, but these errors were encountered: