mirror of
https://github.com/nimbold/Firelink.git
synced 2026-07-27 04:19:19 +00:00
f6851682dd
Transient network drops and Wi-Fi timeouts no longer promote a download straight to a hard Failed state. A shared retry engine classifies the error, emits a transient `Retrying` state, and runs a 3-strike exponential backoff (2s / 5s / 10s) while preserving the active download allocation (semaphore permit / worker slot). Resumability primitives are reused on every retry so no downloaded bytes are discarded. Engine core (src-tauri/src/retry.rs, new): - BACKOFF_SCHEDULE = [2s, 5s, 10s], MAX_RETRIES = 3 - backoff_for(strike): schedule index with graceful clamp beyond range - is_transient_network_error(msg): string classifier covering reqwest, yt-dlp, and aria2c phrasing; permanent conditions (HTTP 401/403/404/ 410/451, not-found, permission denied, out-of-disk) checked first so they always fail fast - backoff_and_emit / backoff_and_emit_cancel: cancel-safe sleep helpers driving a Retrying state emit before each delay - 9 unit tests covering schedule math, clamping, transient vs permanent classification, and permanent-wins-over-transient precedence State model (src-tauri/src/ipc.rs): - DownloadStatus::Retrying variant (serialized "retrying") - DownloadStateEvent::retrying(id, reason) constructor - Regenerated TypeScript binding: src/bindings/DownloadStatus.ts Native reqwest backend (src-tauri/src/download.rs): - DownloadEvent::Retrying variant (headless mirror) - CoordinatorEventSink::emit_retrying() drives the production download-state channel with status "retrying" - download_file retry core rewritten: transient -> emit_retrying -> backoff_for sleep inside a control_rx select (pause/cancel honored mid-backoff) -> re-issue Range header; permanent errors or strike exhaustion advance to the next URL then hard Failed yt-dlp media backend (src-tauri/src/lib.rs): - child spawn+stream loop wrapped in a 3-strike re-spawn loop; stderr tail classified and, if transient, the process is re-spawned after backoff (--continue resumes); --retry-wait=2 added to aria2c downloader aria2c backend (src-tauri/src/queue.rs): - retry-wait=2 option so aria2's internal retries are not rapid-fire - handle_aria2_download_error: intercepts transient onDownloadError, backs off, re-issues addUri, and rotates the stale gid -> id mapping via rotate_aria2_gid (fresh addUri mints a new gid; not rotating would detach subsequent WS events and leak the semaphore permit permanently) - aria2_payloads / aria2_retry_strikes tracking with cleanup on terminal outcomes Verification: cargo build clean; cargo test --lib 37 passed / 0 failed.