Skip to content

Conversation

@kim-em
Copy link
Contributor

@kim-em kim-em commented Feb 11, 2026

This PR ports download resumption from rustup. When a download fails due to a network error, elan now automatically retries once, resuming from where it left off using HTTP Range headers. Also adds a stall timeout (30s at <10 bytes/sec) so downloads no longer hang indefinitely on unreliable connections.

Discussed at https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/.60elan.60.20can't.20resume.20download/near/572363501

Changes

Core download library (src/download/src/lib.rs):

  • curl::download() accepts resume_from: u64 and calls handle.resume_from() (matching rustup)
  • Content-Length adjusted by adding resume_from (server reports remaining bytes; progress needs total)
  • Case-insensitive Content-Length header matching (matching rustup)
  • Stall detection: low_speed_limit(10) + low_speed_time(30s) aborts hung transfers
  • download_to_path_with_backend() handles partial files: checks size, opens in append mode, seeks to end

Retry logic (src/elan-utils/src/utils.rs):

  • On non-client error (not 4xx), automatically retries once with resume_from_partial=true
  • HTTP 416 (Range Not Satisfiable) treated as non-client error, matching rustup

Progress display (src/elan-cli/download_tracker.rs):

  • Handles ResumingPartialDownload notification, resetting speed tracking on resume

🤖 Prepared with Claude Code

kim-em and others added 2 commits February 11, 2026 00:08
Port download resumption from rustup. When a download fails due to a
network error, elan now automatically retries once, resuming from where
it left off using HTTP Range headers. Also adds a stall timeout (30s at
<10 bytes/sec) so downloads no longer hang indefinitely on unreliable
connections.

Closes https://github.com/leanprover/elan/issues/XXX

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review feedback:
- Detect when server returns 200 instead of 206 (ignoring Range header)
  and fall back to a fresh download to avoid data corruption
- On HTTP 416 (Range Not Satisfiable), fall back to fresh download
  instead of permanently failing
- Only treat read-open errors as "no file" for NotFound; propagate
  other errors (permissions, I/O) instead of silently appending

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Any failure to open the partial file (not just NotFound) falls back to
downloaded_so_far=0. This is safe because truncate(downloaded_so_far==0)
ensures a fresh start, and avoids turning a recoverable situation (e.g.
permission error on a temp file) into a hard failure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@Kha
Copy link
Member

Kha commented Feb 11, 2026

Tested? :)

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.

2 participants