← Commit history

v2.0.647 (insiders): pup-bridge#121: stale worker after an upgrade cycles the lane and restores every window; orphaned browser swept at launch + reported by readiness

John Lauer ·e4ab088310 ·1mo ago ·parent c4d0556
4 files changed +29−18
rust/Cargo.lock+12−12
@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"  [[package]] name = "adom-pup-bridge"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-browser",  "pup-cdp",@@ -655,7 +655,7 @@ dependencies = [  [[package]] name = "pup-browser"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-core",  "pup-host",@@ -667,7 +667,7 @@ dependencies = [  [[package]] name = "pup-cdp"-version = "2.0.646"+version = "2.0.647" dependencies = [  "serde_json",  "thiserror",@@ -677,7 +677,7 @@ dependencies = [  [[package]] name = "pup-core"-version = "2.0.646"+version = "2.0.647" dependencies = [  "serde",  "serde_json",@@ -687,7 +687,7 @@ dependencies = [  [[package]] name = "pup-dashboard"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-cdp",  "pup-core",@@ -700,7 +700,7 @@ dependencies = [  [[package]] name = "pup-host"-version = "2.0.646"+version = "2.0.647" dependencies = [  "serde",  "serde_json",@@ -709,14 +709,14 @@ dependencies = [  [[package]] name = "pup-host-mac"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-host", ]  [[package]] name = "pup-host-win"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-core",  "pup-host",@@ -725,7 +725,7 @@ dependencies = [  [[package]] name = "pup-identity"-version = "2.0.646"+version = "2.0.647" dependencies = [  "fontdue",  "image",@@ -735,7 +735,7 @@ dependencies = [  [[package]] name = "pup-session"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-core",  "serde",@@ -745,7 +745,7 @@ dependencies = [  [[package]] name = "pup-vault"-version = "2.0.646"+version = "2.0.647" dependencies = [  "pup-core",  "pup-host",@@ -756,7 +756,7 @@ dependencies = [  [[package]] name = "pup-verbs"-version = "2.0.646"+version = "2.0.647" dependencies = [  "base64",  "png 0.17.16",
rust/Cargo.toml+1−1
@@ -4,7 +4,7 @@ members = ["core", "host", "host-win", "host-mac", "cdp", "browser", "session",  # One version for the whole bridge, in lockstep with src/BRIDGE_VERSION (tools/ship.sh bumps both). [workspace.package]-version = "2.0.646"+version = "2.0.647" edition = "2021" license = "MIT" 
rust/verbs/src/extdrive.rs+15−5
@@ -99,14 +99,24 @@ pub fn reload_stale_worker(ctx: &Ctx) {     let shim = crate::lane_shim(ctx);     let staged = pup_browser::stage_extensions_lane(&*ctx.host, ctx.port, "adom-you", true, Some(&lane), shim);     if staged.is_empty() { pup_core::log("[extdrive] worker reload skipped: re-staging the extension produced nothing".to_string()); return; }-    // 2.0.646 (pup-bridge#121): NEVER reload in place. chrome.runtime.reload() on the running worker broke the-    // channel: every verb on the open windows answered browser_gone while 13 browser processes and the windows-    // were alive (AdomLapper, 2026-09-19). End the lane browser as pup's OWN kill instead: recovery relaunches it-    // on the re-staged extension and restores every window at its last page, the same path a Chrome crash takes.+    // 2.0.646/647 (pup-bridge#121): NEVER reload in place (chrome.runtime.reload() on the running worker broke the+    // channel: every verb answered browser_gone while the windows were alive). And never a bare kill either: 2.0.646+    // killed the lane and recovery FORGOT every window, because the kill had already cleared the pid list that+    // recovery uses to tell pup's own kill from the user closing the last window (AdomLapper, 2026-09-19). This is+    // the crash-restore path, driven on purpose: reserve every extension window, end the lane, relaunch each+    // window from its file on the re-staged extension, in the background, at its last page.+    let files: Vec<Value> = ctx.sessions.all().into_iter().filter(|s| s.transport == "ext").map(|s| s.file_json()).collect();+    let ids: Vec<String> = files.iter().filter_map(|f| f["sessionId"].as_str().map(|s| s.to_string())).collect();+    crate::recovery::reserve(&ids);+    for id in &ids { ctx.sessions.remove(id); }     let n = crate::kill_extdrive(ctx);-    pup_core::log(format!("[extdrive] lane worker {} is behind pup {}; re-staged the extension and ended the lane browser ({n} process(es)) so it comes back on the new files; every window is restored by recovery", have.replace('-', "."), want.replace('-', ".")));+    pup_core::log(format!("[extdrive] lane worker {} is behind pup {}: re-staged the extension and cycled the lane browser ({n} process(es)); relaunching its {} window(s) from their files on the new extension", have.replace('-', "."), want.replace('-', "."), ids.len()));+    for f in files { crate::recovery::relaunch_from_file(ctx, &f); } } +/// 2.0.647: a lane that ends takes its worker version with it; a fresh browser reports its own at hello.+pub fn reset_worker_version() { LANE_WORKER.lock().unwrap().clear(); }+ pub fn lane_worker_stale() -> Option<(String, String)> {     let w = LANE_WORKER.lock().unwrap().clone();     if w.is_empty() { return None; }
rust/verbs/src/lib.rs+1
@@ -102,6 +102,7 @@ pub fn kill_extdrive(ctx: &Ctx) -> u32 {     EXTDRIVE_PIDS.lock().unwrap().clear();     EXTDRIVE_LANE.lock().unwrap().clear();     extdrive::mark_dead();+    extdrive::reset_worker_version();   // 2.0.647: the next hello is the truth, not the last lane's     let _ = std::fs::remove_file(lane_file(ctx));     if n > 0 { pup_core::log(format!("[extdrive] closed {n} browser process(es)")); }     n