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
Discard partial range responses without etag #4563
Discard partial range responses without etag #4563
Conversation
d8d3c69
to
51b4b00
Compare
This seems reasonable! My one caution is to make sure that Bundler actually accepts responses from servers that don't include an etag at all. At the time of my original PR, Bundler would refuse responses with no etag, and act like the compact index didn't exist. If that's no longer the case, sounds like this takes care of everything. 😄 |
Yes. What it does now is falling back to "full update" mode by retrying the request without |
Perfect 👍🏻 |
51b4b00
to
1fa0e6d
Compare
Alright, I keep going a bit in circles here, but at the same time knowing more about the issue. After all you're 100% right when you said:
This is actually how bundler behaved before #3865. Both partial range requests and full requests required an Etag, so we would indeed end up raising a rubygems/bundler/lib/bundler/fetcher/compact_index.rb Lines 70 to 84 in 563933a
So the way bundler behaved before your PR (and after this one if we merge it) is that it falls back to other fetching methods. In the case of sidekiq-pro, to the full index, which works just fine. A theory of why we fixed this in the first place is that some gem servers would provide no Etag and implement no other fetching methods other than the compact index API. If this is the case, yeah, my PR will break them again 😬. So it sounds like I need to go all the way and keep accepting the response without an ETag in case we're requesting a full (not partial) update. |
1fa0e6d
to
ba7f732
Compare
Alright, I implemented only discarding the no etag response when doing a partial update, but accepting it for full updates. This should be finally ready now assuming CI passes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, this looks like exactly what I was thinking. Thanks!
…s_without_etag Discard partial range responses without etag (cherry picked from commit 8e4bb19)
What was the end-user or developer problem that led to this PR?
Some custom gem servers (at least sidekiq's pro one) don't support "incremental API content", yet they respond to partial range responses, providing no Etag.
Previously bundler would handle this just fine, because it would discard the response given and retry a "full range request" in this case.
However, in #3865 we changed bundler to accept the response in this case, which would be appended to the existing response. However, since new versions are not appended to the remote versions file (no "incremental API content"), this would result in a bad response being written to the local client compact index cache. This should be the reason for the problems reported in #4514.
What is your fix for the problem, implemented in this PR?
My fix, for now, is to revert #3865. But as a further improvement, we can keep the "accept the response if no etag" idea, but only if we get a 200 response, not a partial content (206) response.
If we did the latter, sidekiq-pro can fix their server code to always serve full responses, even when requested partial ranges, and things will work in a more efficient way, since it wouldn't require double fallback requests.
EDIT: Extra improvement was also implemented 👍.
Closes #4514.
Closes #4543.
Make sure the following tasks are checked