probe: fix mirrored start deadlock

This commit is contained in:
Brad Stein 2026-05-01 11:13:20 -03:00
parent 0d9121f921
commit 5cf89c2574
7 changed files with 22 additions and 8 deletions

6
Cargo.lock generated
View File

@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]]
name = "lesavka_client"
version = "0.16.15"
version = "0.16.16"
dependencies = [
"anyhow",
"async-stream",
@ -1686,7 +1686,7 @@ dependencies = [
[[package]]
name = "lesavka_common"
version = "0.16.15"
version = "0.16.16"
dependencies = [
"anyhow",
"base64",
@ -1698,7 +1698,7 @@ dependencies = [
[[package]]
name = "lesavka_server"
version = "0.16.15"
version = "0.16.16"
dependencies = [
"anyhow",
"base64",

View File

@ -4,7 +4,7 @@ path = "src/main.rs"
[package]
name = "lesavka_client"
version = "0.16.15"
version = "0.16.16"
edition = "2024"
[dependencies]

View File

@ -1,6 +1,6 @@
[package]
name = "lesavka_common"
version = "0.16.15"
version = "0.16.16"
edition = "2024"
build = "build.rs"

View File

@ -23,7 +23,7 @@ class ProbeState:
self.output_path = output_path
self.status_path = status_path
self.duration_seconds = duration_seconds
self.lock = threading.Lock()
self.lock = threading.RLock()
self.start_token = 0
self.status = {
"booted_at": time.time(),

View File

@ -43,7 +43,7 @@ class StimulusState:
def __init__(self, status_path: Path, args: argparse.Namespace) -> None:
self.status_path = status_path
self.args = args
self.lock = threading.Lock()
self.lock = threading.RLock()
self.start_token = 0
self.status = {
"booted_at": time.time(),

View File

@ -10,7 +10,7 @@ bench = false
[package]
name = "lesavka_server"
version = "0.16.15"
version = "0.16.16"
edition = "2024"
autobins = false

View File

@ -124,3 +124,17 @@ fn local_stimulus_matches_sync_analyzer_pulse_contract() {
);
}
}
#[test]
fn manual_probe_python_servers_use_reentrant_state_locks() {
const BROWSER_CONSUMER: &str = include_str!("../../scripts/manual/browser_consumer_probe.py");
for (name, script) in [
("local stimulus", LOCAL_STIMULUS),
("browser consumer", BROWSER_CONSUMER),
] {
assert!(
script.contains("threading.RLock()"),
"{name} server request handlers call snapshot while holding state lock; use RLock to avoid /start deadlocks"
);
}
}