Repository navigation
fix(nodeenv): retry broken node downloads and stop hanging on stalls - #428
Merged
Merged
Conversation
_download_node_file() retried IncompleteRead only, back to back, and re-raised it as a traceback after the last attempt. A connection reset or timed out in the middle of the body was not retried at all, and urlopen() had no timeout, so a server that stopped sending hung nodeenv forever. Now any OSError while reading the body is retried as well, except HTTPError, which install_node_wrapped() needs for the arm64 -> x64 fallback. The attempts are 3 seconds apart, and the last failure is reported as "Error: cannot download <url>: <reason>" with exit code 1. urllib now waits download_timeout (60) seconds for a server to answer or to send more data. A timeout while waiting for the answer is not wrapped into URLError, so urlopen() reports socket.timeout the same way as an unreachable host. Fixes #324
Contributor
|
Thanks for the fix 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #324
What happens
The
'bytes' object has no attribute 'tell'from the report is gone since #329, which retriesIncompleteReadup to 3 times. Checked against a local server that breaks the download in different ways, master still:IncompleteReadtraceback once all 3 attempts fail, and makes them back to back;ConnectionResetErrortraceback after 1 request);urlopenhas no timeout.Switching to
requests, as the issue suggests, would not help: requests 2.34 / urllib3 2.8 raiseChunkedEncodingErroron the same truncated, chunked and reset bodies. "Multipart" in the title is network truncation.What changes
_download_node_fileretries anyOSErrorwhile reading the body as well, not onlyIncompleteRead.HTTPErroris anOSErrortoo, so it is re-raised first:install_node_wrapped()needs it for the arm64 -> x64 fallback.Error: cannot download <url>: <reason>with exit code 1._urlopenpassestimeout=download_timeout(60 seconds) in all three branches. It is a timeout per socket operation, not for the whole download.URLErroronly while it sends the request; a timeout waiting for the answer comes out as a bareTimeoutError.urlopen()now reportssocket.timeoutthe same way as an unreachable host, so--listagainst a stalled mirror ends with an error message too.Not covered: a body without
Content-Lengththat is cut short looks complete to HTTP and still fails later intarfilewithEOFError, and the npm tarball download ininstall_npmhas no retries.Tests
The new tests fail on master and pass with the fix:
test__download_node_file);urlopen()gives up on a server that accepts the connection and never answers, in each of the three_urlopenbranches.test__download_node_file_leaves_http_errors_to_the_callerpasses on master; it guards theHTTPErrorre-raise, and fails ifOSErroris caught without it.TestCertifi::test_urlopen_without_certifinow checks that nocontextis passed, as its docstring says, instead of empty kwargs.