NimBold f6851682dd feat(retry): add connection-aware exponential backoff across all download backends
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.
2026-06-17 09:16:17 +03:30
2026-06-11 04:03:03 +03:30

Firelink

Firelink

A fast, focused desktop download manager powered by Rust and Tauri.

Version Platform Tauri Rust License CI

Features · Install · Development · Project status

Firelink brings segmented downloads, media extraction, scheduling, and browser integration into one native-feeling desktop application. The current app uses a Rust backend with a React and TypeScript interface, replacing the original SwiftUI implementation.

Features

  • Fast transfers with segmented downloading powered by aria2
  • Media downloads through yt-dlp, FFmpeg, and Deno
  • Persistent queues with configurable concurrency and speed limits
  • Download scheduling with optional post-queue system actions
  • Pause, resume, retry, and duplicate-file handling
  • Smart organization with categories and configurable destinations
  • Browser integration through the Firelink Companion extension
  • Secure local handoff using authenticated extension pairing
  • System integration including tray controls, notifications, and sleep prevention
  • Built-in update checks backed by GitHub Releases

Installation

Important

The Rust and Tauri application is still completing release packaging. The current v0.7.3 macOS asset on GitHub Releases belongs to the archived SwiftUI implementation.

For now, run the maintained application from source using the development instructions below. New packaged builds will be published through GitHub Releases once the migration is complete.

Firelink is currently developed and tested on macOS. Production bundles include the media engines, so packaged releases will not require separate aria2, yt-dlp, FFmpeg, or Deno installations.

Browser Extension

Install Firelink Companion for Firefox to send browser downloads directly to Firelink. Pair the extension from Settings → Integrations using the generated local token.

Project Status

The migration from SwiftUI to Rust, Tauri, React, and TypeScript is in its final stage. The new application is the maintained implementation at the repository root.

Target Status
macOS Active development and automated testing
Windows Core architecture prepared; packaging and validation pending
Linux Core architecture prepared; packaging and validation pending
Legacy SwiftUI app Archived in legacy/swift

See the changelog for release history and recent work.

Development

Requirements

Clone the repository with its browser-extension submodule:

git clone --recurse-submodules https://github.com/nimbold/Firelink.git
cd Firelink

Install dependencies and launch the desktop app:

npm install
npm run tauri dev

Run the frontend build and backend tests:

npm run build
cd src-tauri
cargo test --all-targets

Create a production bundle:

npm run tauri build

Native media executables and runtime files are expected in src-tauri/binaries when running or packaging the application locally.

Repository Structure

.
├── src/                  React and TypeScript interface
├── src-tauri/            Rust backend and Tauri configuration
├── Extensions/Firefox/   Firelink Companion submodule
└── legacy/swift/         Archived SwiftUI application

Technology

License

Firelink is available under the MIT License.

S
Description
Languages
TypeScript 55.2%
Rust 37.4%
JavaScript 3.8%
CSS 3.6%