fix(downloads): reconcile completed aria2 pause requests

This commit is contained in:
NimBold
2026-07-13 04:08:18 +03:30
parent fcfdffa6e0
commit be2a98fbcd
2 changed files with 22 additions and 4 deletions
+16
View File
@@ -3272,6 +3272,22 @@ async fn pause_download(
ensure_aria2_gid_result("forcePause", gid, &result)?;
log::info!("aria2 pause [{}]: gid {} paused", id, gid);
}
"complete" => {
// Aria2 can reach complete before its terminal event updates
// Firelink's row. Treat a pause request in that narrow window
// as an idempotent completion reconciliation, not as an
// actionable pause failure.
log::info!(
"aria2 pause [{}]: gid {} was already complete; reconciling completion",
id,
gid
);
state
.queue_manager
.apply_completion_locked(&id, crate::queue::PendingOutcome::Complete)
.await;
return Ok(());
}
terminal => {
let retrying = state.queue_manager.has_aria2_retry_state(&id).await;
state.queue_manager.clear_aria2_retry_state(&id).await;
+6 -4
View File
@@ -774,10 +774,12 @@ impl<R: tauri::Runtime> QueueManager<R> {
self.apply_completion_locked(id, outcome).await;
}
/// Apply a completion while the caller owns the download control lock.
/// Keeping the epoch transition and terminal cleanup under that lock
/// prevents an old WebSocket event from completing a newer lifecycle.
async fn apply_completion_locked(&self, id: &str, outcome: PendingOutcome) {
/// Apply a terminal outcome while the caller owns the download control
/// lock. Keeping the epoch transition and terminal cleanup under that
/// lock prevents an old WebSocket event from completing a newer lifecycle
/// and lets commands reconcile an Aria2 terminal status without releasing
/// the lock first.
pub(crate) async fn apply_completion_locked(&self, id: &str, outcome: PendingOutcome) {
// A terminal event invalidates every delayed retry or control worker
// from the previous lifecycle before releasing its permit.
self.next_aria2_control_epoch(id).await;