Skip to content

feat(engine): Allow setting max retry per-worker - #100

Merged
YueMiyuki merged 4 commits into
masterfrom
next-dev
Jun 6, 2026
Merged

feat(engine): Allow setting max retry per-worker#100
YueMiyuki merged 4 commits into
masterfrom
next-dev

Conversation

@YueMiyuki

@YueMiyuki YueMiyuki commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary by cubic

Adds a per-worker max retry setting for HTTP downloads, used by both multi-piece workers and the single-connection path. Users can set max-worker-retries (1–20, default 5) in Preferences or config to improve stability on flaky links.

  • New Features

    • Engine honors max-worker-retries for single-connection and multi-piece workers.
    • Preferences: adds “Max retries per worker piece” under Auto Retry; saved as max-worker-retries.
  • Bug Fixes

    • Resuming a task from Error now clears stale error fields so it re-enters the queue properly.

Written for commit c1357bc. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added a "Max retries per worker piece" preference to control retry attempts for transient download errors.
    • Tasks in an error state can now be resumed and requeued; error details are cleared when resuming.
  • Localization

    • Added translations for the new preference label (en‑US and zh‑CN).
  • Chores

    • Normalized JSON formatting and whitespace across package configuration files.

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown

Too many files changed? Review this PR in Change Stack to see how the pieces fit before you dive in.

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 26cb0f42-a53a-429f-be40-698d502e7fb5

📥 Commits

Reviewing files that changed from the base of the PR and between a6a89f0 and c1357bc.

📒 Files selected for processing (3)
  • .gitignore
  • src-tauri/risuko-engine/src/engine/http.rs
  • src-tauri/risuko-engine/src/engine/manager.rs
💤 Files with no reviewable changes (2)
  • src-tauri/risuko-engine/src/engine/manager.rs
  • src-tauri/risuko-engine/src/engine/http.rs

📝 Walkthrough

Walkthrough

Adds a configurable max-worker-retries option threaded from config through single-connection and multi-chunk download paths, exposes a bounded NumberInput in preferences with i18n, allows unpausing tasks in Error, and normalizes JSON formatting across many package.json manifests.

Changes

Worker Retry Budget Configuration

Layer / File(s) Summary
Configuration key registration and localization
src/shared/configKeys.ts, src/shared/locales/en-US/preferences.ts, src/shared/locales/zh-CN/preferences.ts
Adds max-worker-retries to system config keys and supplies English and Chinese preference labels.
User config override allowlist
src-tauri/risuko-engine/src/engine/options.rs
Allows max-worker-retries values from user config to override engine options.
Preferences UI control and form handling
src/renderer/components/Preference/Basic.vue
Adds conditional NumberInput for workerMaxRetries when auto-retry is enabled; init and submit normalize value to 1..20 (default 5).
Engine-side retry parameter threading and usage
src-tauri/risuko-engine/src/engine/http.rs
Parses max-worker-retries (min 1, default previous constant), forwards it into run_multi_chunkpiece_worker, and replaces fixed retry budget checks with the configured max_retries; updates some debug/log formatting.
Task unpause from error state
src-tauri/risuko-engine/src/engine/manager.rs
TaskManager::unpause now accepts Paused or Error; clears error_code/error_message when resuming from Error.

Sequence diagram (high-level request flow):

sequenceDiagram
  participant Config
  participant RunSingleUri
  participant RunMultiChunk
  participant PieceWorker
  Config->>RunSingleUri: supply "max-worker-retries"
  RunSingleUri->>RunMultiChunk: pass max_retries
  RunMultiChunk->>PieceWorker: spawn with max_retries
  PieceWorker->>PieceWorker: check retry_count vs max_retries on error/EOF
Loading

Manifest formatting Normalization

Layer / File(s) Summary
Reformat package.json files
packages/risuko-app/package.json, packages/risuko-cli/..., packages/risuko-js/...
Whitespace/indentation normalization across many npm package.json files; no metadata values or semantics changed. Additionally updates .gitignore to ignore *.node and content.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • YueMiyuki/Risuko#96: Overlaps in single-connection auto-resume retry behavior changes in http.rs.

Poem

🐰 I nibble config carrots, tidy retries with care,

Workers hop back bravely when errors clear the air,
A NumberInput blooms where auto-retry lies,
Locales whisper labels in English and Chinese,
Hop—retries bounded, downloads fair!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(engine): Allow setting max retry per-worker' accurately describes the main change: adding a configurable per-worker maximum retry setting for HTTP downloads.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the next The "next" steps label Jun 5, 2026

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src-tauri/risuko-engine/src/engine/http.rs`:
- Around line 862-869: The code calculating max_worker_retries may truncate a
large u64 when casting to u32; modify the chain that builds max_worker_retries
so you clamp the u64 value into the u32 range before casting (e.g. apply
.max(1).min(u64::from(u32::MAX)) on the u64 and only then cast to u32), keeping
the existing fallback to CHUNK_MAX_RETRIES and the initial parsing logic on
options.get("max-worker-retries").
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4608a221-7520-48b7-8769-6e4a9686f2aa

📥 Commits

Reviewing files that changed from the base of the PR and between 1ca8a2d and 8ef4da7.

📒 Files selected for processing (22)
  • packages/risuko-app/package.json
  • packages/risuko-cli/npm/darwin-arm64/package.json
  • packages/risuko-cli/npm/darwin-x64/package.json
  • packages/risuko-cli/npm/linux-arm64-gnu/package.json
  • packages/risuko-cli/npm/linux-x64-gnu/package.json
  • packages/risuko-cli/npm/win32-arm64-msvc/package.json
  • packages/risuko-cli/npm/win32-x64-msvc/package.json
  • packages/risuko-cli/package.json
  • packages/risuko-js/npm/darwin-arm64/package.json
  • packages/risuko-js/npm/darwin-x64/package.json
  • packages/risuko-js/npm/linux-arm64-gnu/package.json
  • packages/risuko-js/npm/linux-x64-gnu/package.json
  • packages/risuko-js/npm/win32-arm64-msvc/package.json
  • packages/risuko-js/npm/win32-x64-msvc/package.json
  • packages/risuko-js/package.json
  • src-tauri/risuko-engine/src/engine/http.rs
  • src-tauri/risuko-engine/src/engine/manager.rs
  • src-tauri/risuko-engine/src/engine/options.rs
  • src/renderer/components/Preference/Basic.vue
  • src/shared/configKeys.ts
  • src/shared/locales/en-US/preferences.ts
  • src/shared/locales/zh-CN/preferences.ts

Comment thread src-tauri/risuko-engine/src/engine/http.rs

@cubic-dev-ai cubic-dev-ai Bot 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.

3 issues found across 22 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src-tauri/risuko-engine/src/engine/http.rs Outdated
Comment thread src-tauri/risuko-engine/src/engine/manager.rs
Comment thread src-tauri/risuko-engine/src/engine/http.rs

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src-tauri/risuko-engine/src/engine/manager.rs (1)

2390-2396: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Error→unpause moves torrent tasks into a non-runnable state.

At Line 2392, torrents resumed from Error are set to Waiting. But this file only drives torrent runtime/resolver paths for Active torrents, and try_start_next does not activate waiting torrents, so these tasks can stay stuck.

Suggested minimal fix
-            let was_error = task.status == TaskStatus::Error;
             is_torrent = task.kind == TaskKind::Torrent;
-            if is_torrent && !was_error {
+            if is_torrent {
                 task.status = TaskStatus::Active;
             } else {
                 task.status = TaskStatus::Waiting;
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src-tauri/risuko-engine/src/engine/manager.rs` around lines 2390 - 2396, The
resume logic currently sets a resumed torrent (task.kind == TaskKind::Torrent)
that was in Error back to Waiting, which prevents torrent runtime/resolver paths
from running; update the branch in the code around the TaskStatus handling so
that if is_torrent is true and was_error is true (i.e., task.kind ==
TaskKind::Torrent && task.status was TaskStatus::Error) you set task.status =
TaskStatus::Active instead of Waiting; adjust the conditional around task.status
assignment near the existing variables (was_error, is_torrent) so torrents
resumed from Error become Active and ensure this change aligns with
try_start_next expectations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src-tauri/risuko-engine/src/engine/manager.rs`:
- Around line 2390-2396: The resume logic currently sets a resumed torrent
(task.kind == TaskKind::Torrent) that was in Error back to Waiting, which
prevents torrent runtime/resolver paths from running; update the branch in the
code around the TaskStatus handling so that if is_torrent is true and was_error
is true (i.e., task.kind == TaskKind::Torrent && task.status was
TaskStatus::Error) you set task.status = TaskStatus::Active instead of Waiting;
adjust the conditional around task.status assignment near the existing variables
(was_error, is_torrent) so torrents resumed from Error become Active and ensure
this change aligns with try_start_next expectations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 83c1485a-0958-4b46-8387-530dc7b07be2

📥 Commits

Reviewing files that changed from the base of the PR and between 8ef4da7 and 5b5c7f0.

📒 Files selected for processing (2)
  • src-tauri/risuko-engine/src/engine/http.rs
  • src-tauri/risuko-engine/src/engine/manager.rs

@coderabbitai coderabbitai Bot 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src-tauri/risuko-engine/src/engine/manager.rs (1)

2386-2396: 🧹 Nitpick | 🔵 Trivial | 💤 Low value

Unused variable was_error.

The variable was_error is declared on line 2390 but never used. This appears to be dead code—possibly a leftover from a removed conditional, or intended for differentiated logging/events that wasn't implemented.

If the distinction between "resume from Paused" vs "retry from Error" isn't needed for logging or event emission, remove the variable to avoid confusion.

🧹 Suggested cleanup
             if task.status == TaskStatus::Error {
                 task.error_code = None;
                 task.error_message = None;
             }
-            let was_error = task.status == TaskStatus::Error;
             is_torrent = task.kind == TaskKind::Torrent;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src-tauri/risuko-engine/src/engine/manager.rs` around lines 2386 - 2396, The
local variable was_error is declared but never used; remove the dead variable
declaration (was_error) from the block that checks TaskStatus::Error and sets
task.status, leaving the existing logic that clears
task.error_code/error_message and updates task.status based on task.kind
(TaskKind::Torrent) and TaskStatus::Active/Waiting so no behavior changes occur.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src-tauri/risuko-engine/src/engine/manager.rs`:
- Around line 2386-2396: The local variable was_error is declared but never
used; remove the dead variable declaration (was_error) from the block that
checks TaskStatus::Error and sets task.status, leaving the existing logic that
clears task.error_code/error_message and updates task.status based on task.kind
(TaskKind::Torrent) and TaskStatus::Active/Waiting so no behavior changes occur.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 549ad02f-2c93-41ba-9c65-a90c688ccf2c

📥 Commits

Reviewing files that changed from the base of the PR and between 5b5c7f0 and a6a89f0.

📒 Files selected for processing (1)
  • src-tauri/risuko-engine/src/engine/manager.rs

@YueMiyuki YueMiyuki linked an issue Jun 6, 2026 that may be closed by this pull request
6 tasks
@YueMiyuki
YueMiyuki merged commit 918e960 into master Jun 6, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

next The "next" steps

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: 任务列表计数混乱,“等待中”的任务无法自动开始

1 participant