chore(release): stage v1.7.52-alpha
This commit is contained in:
@@ -313,6 +313,7 @@ impl Server {
|
||||
let scanner = create_docker_scanner(&config).await?;
|
||||
let state = state_manager.clone();
|
||||
let identity_clone = identity.clone();
|
||||
let data_dir = config.data_dir.clone();
|
||||
let scan_kick = api_handler.rpc_handler().scan_kick();
|
||||
let scan_tick = api_handler.rpc_handler().scan_tick();
|
||||
|
||||
@@ -334,6 +335,7 @@ impl Server {
|
||||
&scanner,
|
||||
&state,
|
||||
identity_clone.as_ref(),
|
||||
&data_dir,
|
||||
&mut absence_tracker,
|
||||
&mut transitional_since,
|
||||
)
|
||||
@@ -371,6 +373,7 @@ impl Server {
|
||||
&scanner,
|
||||
&state,
|
||||
identity_clone.as_ref(),
|
||||
&data_dir,
|
||||
&mut absence_tracker,
|
||||
&mut transitional_since,
|
||||
)
|
||||
@@ -865,8 +868,19 @@ fn merge_preserving_transitional(
|
||||
existing: &crate::data_model::PackageDataEntry,
|
||||
fresh: &crate::data_model::PackageDataEntry,
|
||||
) -> crate::data_model::PackageDataEntry {
|
||||
let state = match (&existing.state, &fresh.state) {
|
||||
// Removing with a live running container is stale: uninstall either
|
||||
// failed or Archipelago restarted before the spawned task could revert
|
||||
// state. Let the scanner recover the UI immediately instead of
|
||||
// keeping the app wedged in Removing for 20 minutes.
|
||||
(crate::data_model::PackageState::Removing, crate::data_model::PackageState::Running) => {
|
||||
fresh.state.clone()
|
||||
}
|
||||
_ => existing.state.clone(),
|
||||
};
|
||||
|
||||
crate::data_model::PackageDataEntry {
|
||||
state: existing.state.clone(),
|
||||
state,
|
||||
// install_progress and uninstall_stage are also owned by the
|
||||
// initiating op (same reason as state) — keep them.
|
||||
install_progress: existing.install_progress.clone(),
|
||||
@@ -885,10 +899,18 @@ async fn scan_and_update_packages(
|
||||
scanner: &DockerPackageScanner,
|
||||
state: &StateManager,
|
||||
identity: &NodeIdentity,
|
||||
data_dir: &std::path::Path,
|
||||
absence_tracker: &mut HashMap<String, u32>,
|
||||
transitional_since: &mut HashMap<String, Instant>,
|
||||
) -> Result<()> {
|
||||
let packages = scanner.scan_containers().await?;
|
||||
let mut packages = scanner.scan_containers().await?;
|
||||
let user_stopped = crate::crash_recovery::load_user_stopped(data_dir).await;
|
||||
for (id, pkg) in packages.iter_mut() {
|
||||
if pkg.state == crate::data_model::PackageState::Exited && user_stopped.contains(id) {
|
||||
pkg.state = crate::data_model::PackageState::Stopped;
|
||||
pkg.exit_code = None;
|
||||
}
|
||||
}
|
||||
|
||||
let (current_data, _) = state.get_snapshot().await;
|
||||
let tor_addr = docker_packages::read_tor_address("archipelago").await;
|
||||
@@ -992,6 +1014,18 @@ async fn scan_and_update_packages(
|
||||
// owner (spawn_task) is responsible for clearing state, not us.
|
||||
if let Some(entry) = merged.get(&id) {
|
||||
if is_transitional(&entry.state) {
|
||||
let entered = *transitional_since.entry(id.clone()).or_insert(now);
|
||||
if now.duration_since(entered) > TRANSITIONAL_STUCK_TIMEOUT {
|
||||
warn!(
|
||||
"Container {} stuck in {:?} and absent for >{}s; removing stale transitional state",
|
||||
id,
|
||||
entry.state,
|
||||
TRANSITIONAL_STUCK_TIMEOUT.as_secs()
|
||||
);
|
||||
merged.remove(&id);
|
||||
transitional_since.remove(&id);
|
||||
changed = true;
|
||||
}
|
||||
absence_tracker.remove(&id);
|
||||
continue;
|
||||
}
|
||||
@@ -1170,6 +1204,15 @@ mod merge_tests {
|
||||
assert_eq!(merged.exit_code, Some(0));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn stale_removing_recovers_when_container_is_running() {
|
||||
let existing = make_entry(PackageState::Removing, Some("unknown"));
|
||||
let fresh = make_entry(PackageState::Running, Some("healthy"));
|
||||
let merged = merge_preserving_transitional(&existing, &fresh);
|
||||
assert_eq!(merged.state, PackageState::Running);
|
||||
assert_eq!(merged.health.as_deref(), Some("healthy"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn is_transitional_covers_all_variants() {
|
||||
for s in [
|
||||
|
||||
Reference in New Issue
Block a user