-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
DeflateStream behavior for partial results #53502
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @carlossanlop Issue DetailsI'm trying to use What I might be doing differently from the standard approach is that I'm using a single long running stream and expecting to read partial results from the stream. What I observed is that when I'm using For reference, I have a reproduction of the problem below. This simulates a stream that has some compressed data, but not all of it.
On the other hand, in the case of the This is the part that is responsible for this: In the There is another issue here, which that on 6.0, it seems that the The scenario is very important for wrapping a network connection with a As mentioned, here is the reproduction for this issue.
|
Can you share the code that produced the data you're trying to decompress? |
Here is it with clean data, in the code above, replace the
And the code to generate this is using:
You can observe the same behavior difference between |
It appears DeflateStream.Read has always tried to fill the destination buffer. I agree that's un-Stream-like. I don't know why it was done that way, but it's that way in .NET Framework as well. ReadAsync was just a wrapper for Read until a few versions ago, when it was written to actually be async; that implementation had a few bugs, which have been fixed in .NET 6 by simplifying it and having it mirror the Read implementation, since they should behave identically, albeit with one doing sync I/O and the other doing async I/O. But, as you point out, that's now imbued ReadAsync with the same "fill the destination buffer" behavior that Read had and that ReadAsync also had for most of its existence (but didn't in .NET 5). It's worth looking at changing both implementations in .NET 6. cc: @geoffkizer |
I can submit a PR for that, if this is OK |
Thanks. I have a fix (also addressing a long-standing issue around 0-byte reads), but I want to do some perf validation to understand what the impact will be; it was almost certainly written like this initially to reduce various costs. |
I'm trying to use
DeflateStream
(actuallyGZipStream
but the issue is with theDeflateStream
code) to reduce the amount of data that I'm sending over the wire.What I might be doing differently from the standard approach is that I'm using a single long running stream and expecting to read partial results from the stream.
What I observed is that when I'm using
Read()
, the operation hangs and when I'm usingReadAsync()
, I'm able to process partial responses properly.For reference, I have a reproduction of the problem below. This simulates a stream that has some compressed data, but not all of it.
When I'm calling
Read()
on theGZipStream
, the underlying deflate will only return on one of the following conditions:On the other hand, in the case of the
ReadAsync()
, if we have data available from in the user's buffer, we'll return immediately to the user with whatever we have at hand.This is the part that is responsible for this:
https://github.com/dotnet/runtime/blob/v5.0.6/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs#L482-L486
In the
Read()
implementation, however, there is no such check.My guess is that it should go here:
https://github.com/dotnet/runtime/blob/v5.0.6/src/libraries/System.IO.Compression/src/System/IO/Compression/DeflateZLib/DeflateStream.cs#L272
There is another issue here, which that on 6.0, it seems that the
ReadAsync()
implementation has been made identical to theRead()
implementation and in both cases they would hang on partial responses.The scenario is very important for wrapping a network connection with a
GZipStream
and reading potentially small values from it.As mentioned, here is the reproduction for this issue.
@ayende
The text was updated successfully, but these errors were encountered: