Skip to content

Resume server-interrupted downloads - #5177

Open
djc wants to merge 7 commits into
mainfrom
resume-interrupted-downloads
Open

djc wants to merge 7 commits into
mainfrom
resume-interrupted-downloads

Conversation

@djc

@djc djc commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

Fixes #5176.

(With help from Claude.)

@djc
djc requested a review from rami3l October 30, 2026 09:41
@djc
djc force-pushed the resume-interrupted-downloads branch from dc7a05f to be81569 Compare October 30, 2026 09:50
@djc
djc force-pushed the resume-interrupted-downloads branch from be81569 to de883d7 Compare October 30, 2026 10:07
@djc
djc marked this pull request as ready for review October 30, 2026 10:07
@rami3l

rami3l commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

@iliana @Skgland Would you mind giving our test build a try and see if rustup can better handle your network connection? You can download the corresponding one for your host at https://github.com/rust-lang/rustup/actions/runs/41038394164 🙏

Comment thread src/download/mod.rs
#[cfg(any(feature = "reqwest-rustls-tls", feature = "reqwest-native-tls"))]
Some(DownloadError::Reqwest(e)) => e.is_timeout() || e.is_connect(),
#[cfg(any(feature = "reqwest-rustls-tls", feature = "reqwest-native-tls"))]
Some(DownloadError::Interrupted(_)) => true,

@rami3l rami3l Oct 30, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Is this payload always ignored, and if so maybe we should just forget about it?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand what you mean. We're streaming frames of data from the HTTP response onto disk. When an error occurs after we've streamed some frames, why not preserve what we've downloaded so we can resume from it later?

@rami3l rami3l Oct 30, 2026 •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not being super clear previously, but I mean that payload in DownloadError::Interrupted(payload) is always matched as _ (discarded). Does this mean that there is no point in saving it in the first place?

@rami3l rami3l changed the title Resume interrupted downloads Resume server-interrupted downloads Oct 30, 2026

@rami3l rami3l left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, although I'd love if this can be tested before being merged 🙏

PS: Also changed the patch's title to make it clear that this is resuming server-interrupted downloads (instead of user-interrupted downloads which we already support).

View changes since this review

@djc

djc commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

LGTM, although I'd love if this can be tested before being merged 🙏

Testing it isn't really trivial -- the dist test fixtures are using file:// URLs and so far we don't have a HTTP server for them AIUI. We'd also need a much larger file.

@rami3l

rami3l commented Oct 30, 2026

Copy link
Copy Markdown
Member

LGTM, although I'd love if this can be tested before being merged 🙏

Testing it isn't really trivial -- the dist test fixtures are using file:// URLs and so far we don't have a HTTP server for them AIUI. We'd also need a much larger file.

I totally understand that, and that is why I think some manual testing could be helpful here. 🙏

@Skgland

Skgland commented Oct 30, 2026

Copy link
Copy Markdown
Contributor

@iliana @Skgland Would you mind giving our test build a try and see if rustup can better handle your network connection? You can download the corresponding one for your host at https://github.com/rust-lang/rustup/actions/runs/41038394164 🙏

I won't be able to try it before sunday.

@iliana

iliana commented Oct 30, 2026

Copy link
Copy Markdown

With this change on my system I am now able to get toolchains to install, although I did hit:

info: checking for self-update (current version: 1.30.0)
info: downloading self-update (new version: 1.29.2)
error: could not download file from 'https://static.rust-lang.org/rustup/archive/1.29.2/x86_64-unknown-linux-gnu/rustup-init' to '/home/iliana/.rustup/self-update/rustup-init': error decoding response body: request or response body error: error reading a body from connection: connection reset

The behavior is now tolerable but still annoying compared to the curl backend due to what seem like sleeps/exponential backoff between retries. curl might be experiencing the same connection resets but retrying without any backoff, I'm not entirely sure.

@rami3l

rami3l commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

With this change on my system I am now able to get toolchains to install, although I did hit:

info: checking for self-update (current version: 1.30.0)
info: downloading self-update (new version: 1.29.2)
error: could not download file from 'https://static.rust-lang.org/rustup/archive/1.29.2/x86_64-unknown-linux-gnu/rustup-init' to '/home/iliana/.rustup/self-update/rustup-init': error decoding response body: request or response body error: error reading a body from connection: connection reset

The behavior is now tolerable but still annoying compared to the curl backend due to what seem like sleeps/exponential backoff between retries. curl might be experiencing the same connection resets but retrying without any backoff, I'm not entirely sure.

@iliana As I explained above, rustup's curl backend doesn't expose this behavior because it's too old to support http2; we are trying to improve http2 support here so there is no parity to be reached WRT the libcurl backend. Removing http2 support or defaulting to http1.1 when using the reqwest backend is NOT an option here for us.

@iliana

iliana commented Oct 30, 2026

Copy link
Copy Markdown

That makes sense! Sorry I missed that explanation.

@djc

djc commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

The behavior is now tolerable but still annoying compared to the curl backend due to what seem like sleeps/exponential backoff between retries. curl might be experiencing the same connection resets but retrying without any backoff, I'm not entirely sure.

How do you sleeps/exponential backoffs? I don't think we have those? If there is something we could maybe avoid it for this particular failure mode.

@djc

djc commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

@iliana As I explained above, rustup's curl backend doesn't expose this behavior because it's too old to support http2; we are trying to improve http2 support here so there is no parity to be reached WRT the libcurl backend. Removing http2 support or defaulting to http1.1 when using the reqwest backend is NOT an option here for us.

But, maybe there is a way to fall back to HTTP/1 in failure cases? Not sure how easy reqwest makes that sort of thing.

@iliana

iliana commented Oct 30, 2026

Copy link
Copy Markdown

How do you sleeps/exponential backoffs? I don't think we have those?

Here's what I see: https://asciinema.org/a/7eDycB7rXUMn1WLX

This may simply be the amount of time it takes to start the connection + request again?

@djc

djc commented Oct 30, 2026

Copy link
Copy Markdown
Contributor Author

How do you sleeps/exponential backoffs? I don't think we have those?

Here's what I see: https://asciinema.org/a/7eDycB7rXUMn1WLX

This may simply be the amount of time it takes to start the connection + request again?

Yeah, the delay in retrying is a little surprising. Also, I guess we should retry the rustup self-update download, as well?

Still, seems like this PR provides a decent improvement, in that your toolchain component downloads can now actually complete.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

default download backend gets repeated connection resets; curl backend does not

4 participants