Skip to content

rustup: retry rustup-mirror on transient network failures - #213

Open
yaoge123 wants to merge 1 commit into
tuna:masterfrom
yaoge123:rustup-retry
Open

yaoge123 wants to merge 1 commit into
tuna:masterfrom
yaoge123:rustup-retry

Conversation

@yaoge123

@yaoge123 yaoge123 commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Pass --retries "${RUSTUP_RETRIES:-3}" through to rustup-mirror, enabling its built-in per-file retry for transient download failures.

Why

A single connection timeout to static.rust-lang.org fails the whole rustup sync run, and the job then shows as failed until the next scheduled attempt. We see this intermittently on mirror.nju.edu.cn, where direct connections to static.rust-lang.org time out.

rustup-mirror 0.12.0 (jiegec/rustup-mirror@c0c6fcb) retries transient per-file download failures with exponential backoff and exposes --retries (default 3). Per-file retry is the right layer for this: a wrapper loop around the whole invocation would re-run the manifest walk and --gc on every attempt, multiply with the inner backoff, and retry permanent errors N times — so the wrapper loop this PR started with was dropped per review.

Environment variables

Variable Default Meaning
RUSTUP_RETRIES 3 per-file download attempts, passed to rustup-mirror --retries

(MIRROR_BASE_URL and RUSTUP_GC behave as before.)

Testing

Running in production on mirror.nju.edu.cn, where direct connections to static.rust-lang.org time out intermittently; with per-file retry the job completes reliably.

Deployment

Requires rustup-mirror ≥ 0.12.0 in the image — earlier versions have no --retries flag and would fail on the unknown option. The image builds from crates.io max_stable_version, so the next image rebuild picks up 0.12.0.

Copilot AI lite review requested due to automatic review settings September 23, 2026 15:41

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Avoid logging and sleeping after the final failed attempt.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
What changed in this PR

Adds retry handling to rustup-mirror for transient network failures.

Changes:

  • Retries synchronization up to three times.
  • Waits 60 seconds between attempts.
  • Preserves failure status after all attempts fail.
File Description
rustup.sh Adds retry handling around rustup-mirror.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread rustup.sh Outdated
@yaoge123

Copy link
Copy Markdown
Contributor Author

Verified: the Copilot review item is already resolved on this branch. The final failed attempt logs giving up and exits without the extra sleep (fixed in 8f313ba; the guard was carried over when retries were raised to 30x10s in f3f3594). No further changes needed.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟡 Changes recommended

Align the retry loop with the advertised attempt and delay policy.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 Medium severity

Open (1)
Resolved since last review (1)

Comment thread rustup.sh Outdated
Comment on lines +15 to +22
for i in $(seq 1 30); do
if /usr/local/cargo/bin/rustup-mirror -u "${BASE_URL}" -m "${TUNASYNC_WORKING_DIR}" --gc "${GC}"; then
ok=1
break
fi
if [[ $i -lt 30 ]]; then
echo "rustup-mirror attempt $i failed, retrying in 10s"
sleep 10
@yaoge123

Copy link
Copy Markdown
Contributor Author

Round-2 review item addressed: the retry policy is now named constants RETRY_ATTEMPTS=30 / RETRY_DELAY=10 at the top of the script, used by the loop bound, the guard, and the sleep (de7fbab). The PR description has been updated to state the actual policy (30 attempts, 10s apart) instead of the original 3x60s.

@happyaron happyaron 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.

rustup-mirror v0.12.0 (released today, includes jiegec/rustup-mirror@c0c6fcb) now retries transient download failures per file with exponential backoff instead of panicking, and exposes --retries (default 3). Since our image builds from crates.io max_stable_version, the next image rebuild picks this up.

Given that, could we drop the whole-run retry loop and instead pass the flag through, e.g. --retries "${RUSTUP_RETRIES:-3}", so NJU can raise it via env? A per-file retry avoids re-running the manifest walk and --gc up to 30 times, and doesn't multiply with the inner backoff. It also won't retry permanent errors 30 times.

If you still see failures on 0.12.0 that the per-file retry doesn't cover, happy to revisit the outer loop. In that case please make RETRY_ATTEMPTS/RETRY_DELAY env-overridable like RUSTUP_GC.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Copilot review overview

🟢 Approval recommended

No unresolved review issues were identified.

Review effort: Lite
Findings: 1 Medium severity

Open (1)

@yaoge123

Copy link
Copy Markdown
Contributor Author

@happyaron Agreed and done in b57386a: the wrapper retry loop is dropped and the script now passes --retries "${RUSTUP_RETRIES:-3}" straight through, so the policy is env-overridable like RUSTUP_GC. Per-file retry with backoff is clearly the better layer for this — no repeated manifest walks, no retrying permanent errors 30 times. The PR description has been updated to match.

One deployment note from our side: the current production image still ships rustup-mirror 0.11.0 (no --retries flag), so we'll hold this version of the script on our production copy until the image is rebuilt with 0.12.0; the loop version stays there in the meantime.

A single connection timeout to static.rust-lang.org fails the whole
rustup sync run, and the job then shows as failed until the next
scheduled attempt. We see this intermittently on mirror.nju.edu.cn,
where direct connections to static.rust-lang.org time out.

rustup-mirror 0.12.0 (jiegec/rustup-mirror@c0c6fcb) retries transient
per-file download failures with exponential backoff and exposes
--retries (default 3). Pass the flag through as
--retries "${RUSTUP_RETRIES:-3}" so the policy is env-overridable like
RUSTUP_GC.

A wrapper retry loop around the whole rustup-mirror invocation was
considered and dropped per review: per-file retry avoids re-running
the manifest walk and --gc on every attempt, does not multiply with
the inner backoff, and does not retry permanent errors N times.

Deployment note: requires rustup-mirror >= 0.12.0 in the image
(previous versions have no --retries flag).
@yaoge123

Copy link
Copy Markdown
Contributor Author

Branch cleanup note: this branch has been squashed to a single commit, dd924bd. All commit SHAs referenced earlier in the review threads (bdbde69, 8f313ba, f3f3594, de7fbab, b57386a) are now orphaned commits — the links still open, but please rely on the current diff, whose tree is byte-identical to the previous head b57386a.

Review items → how they were addressed (all included in the current diff)

  • Retry loop slept 60 s after the final failed attempt (Copilot round 1) → fixed at the time; moot now because the loop itself is gone.
  • Loop policy (30×10 s) did not match the described 3×60 s (Copilot round 2) → superseded: the wrapper loop was dropped entirely, so there is no loop policy left to misdescribe.
  • Drop the whole-run retry loop and pass --retries through instead (@happyaron) → done exactly as suggested: the script now passes --retries "${RUSTUP_RETRIES:-3}" to rustup-mirror, env-overridable like RUSTUP_GC. Per-file retry with backoff avoids re-running the manifest walk and --gc on every attempt and does not retry permanent errors N times.

Deployment note (unchanged): the script now requires rustup-mirror ≥ 0.12.0 in the image; our production copy keeps the loop version until the image is rebuilt.

Some earlier in-thread replies described intermediate states of the branch; please rely on the current diff and this summary.

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.

3 participants