mirror of
https://github.com/nimbold/Firelink.git
synced 2026-09-01 13:38:01 +00:00
fix(queue): preserve lifecycle ownership during recovery
Require queue-permit ownership before resuming a paused GID and rebuild a job when its GID disappears during recovery. Advance the Browser companion with the automatic-capture handoff guard for #28.
This commit is contained in:
+1
-1
Submodule Extensions/Browser updated: bd3c7e0b4a...2ee1f37921
@@ -4598,7 +4598,7 @@ async fn resume_download(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(permit) = permit_candidate {
|
if let Some(permit) = permit_candidate {
|
||||||
let _ = queue_manager
|
let parked = queue_manager
|
||||||
.park_aria2_permit_if_missing_for_queue(
|
.park_aria2_permit_if_missing_for_queue(
|
||||||
&id_clone,
|
&id_clone,
|
||||||
&queue_id,
|
&queue_id,
|
||||||
@@ -4606,6 +4606,14 @@ async fn resume_download(
|
|||||||
permit,
|
permit,
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
if !parked {
|
||||||
|
log::warn!(
|
||||||
|
"aria2 resume [{}]: permit ownership was not established before unpause; leaving gid {} paused",
|
||||||
|
id_clone,
|
||||||
|
gid_clone
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let _ = app_handle_clone.emit(
|
let _ = app_handle_clone.emit(
|
||||||
"download-state",
|
"download-state",
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ pub enum Aria2RecreateOutcome {
|
|||||||
Unavailable(String),
|
Unavailable(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn aria2_recovery_should_rebuild_after_pause_error(status: &str) -> bool {
|
||||||
|
status == "removed"
|
||||||
|
}
|
||||||
|
|
||||||
/// What kind of sidecar a queued task spawns. Drives which runner the
|
/// What kind of sidecar a queued task spawns. Drives which runner the
|
||||||
/// dispatcher invokes.
|
/// dispatcher invokes.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -2824,6 +2828,16 @@ impl SidecarSpawner for ProductionSpawner {
|
|||||||
Ok(status) if status == "complete" => {
|
Ok(status) if status == "complete" => {
|
||||||
return Ok(Aria2RecreateOutcome::Complete);
|
return Ok(Aria2RecreateOutcome::Complete);
|
||||||
}
|
}
|
||||||
|
Ok(status)
|
||||||
|
if aria2_recovery_should_rebuild_after_pause_error(&status) =>
|
||||||
|
{
|
||||||
|
log::warn!(
|
||||||
|
"aria2 connection recovery [{}]: gid {} disappeared after forcePause failed; rebuilding from the saved payload: {}",
|
||||||
|
id,
|
||||||
|
gid,
|
||||||
|
error
|
||||||
|
);
|
||||||
|
}
|
||||||
Ok(status) => {
|
Ok(status) => {
|
||||||
return Err(format!(
|
return Err(format!(
|
||||||
"failed to pause aria2 gid {gid} before recreation: {error}; daemon reports {status}"
|
"failed to pause aria2 gid {gid} before recreation: {error}; daemon reports {status}"
|
||||||
@@ -3128,6 +3142,13 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn aria2_recovery_rebuilds_when_force_pause_races_with_removal() {
|
||||||
|
assert!(aria2_recovery_should_rebuild_after_pause_error("removed"));
|
||||||
|
assert!(!aria2_recovery_should_rebuild_after_pause_error("paused"));
|
||||||
|
assert!(!aria2_recovery_should_rebuild_after_pause_error("active"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn aria2_connection_options_clamp_untrusted_connection_counts() {
|
fn aria2_connection_options_clamp_untrusted_connection_counts() {
|
||||||
let mut options = serde_json::Map::new();
|
let mut options = serde_json::Map::new();
|
||||||
|
|||||||
Reference in New Issue
Block a user