Rename kamil_adc to rph_radar and fix its data path

This commit is contained in:
Ayzen
2026-10-06 18:15:18 +03:00
parent aef549ea76
commit a185e61495
94 changed files with 2851 additions and 9485 deletions
+2 -41
View File
@@ -24,10 +24,7 @@ logger = logging.getLogger(__name__)
_LOG_MAX_BYTES = 8 * 1024 * 1024
# Per-process force-kill deadline used on stop; each child gets its own window.
_STOP_GRACE_SECONDS = 2.0
# Cmdline marker for the Kamil ADC collector binary. The collector runs in its own
# session, so it can outlive a force-killed acquisition producer while still holding
# the L-Card E-502; we hunt it by name as a guaranteed device-release backstop.
_KAMIL_COLLECTOR_MARKER = b"kamil_adc_collector"
@dataclass(slots=True)
@@ -143,9 +140,6 @@ class ProcessSupervisor:
"""Start required pipeline binaries and wait until they are ready."""
if self.is_running():
raise RuntimeError("Acquisition processes are already running")
# Clean slate: an ADC collector orphaned by a prior crash/force-kill can
# still hold the E-502 and make a fresh acquisition fail to open.
self._kill_kamil_collectors()
logger.info(
"Starting pipeline from config %s (allow_clean_acquisition_exit=%s)",
@@ -197,7 +191,6 @@ class ProcessSupervisor:
def stop(self) -> None:
"""Stop acquisition-side processes, keep processor process intact."""
self._stop_processes(["acquisition", "data_preprocessor"])
self._kill_kamil_collectors()
def stop_acquisition(self) -> None:
"""Stop acquisition process only."""
@@ -210,7 +203,6 @@ class ProcessSupervisor:
def stop_all(self) -> None:
"""Stop all managed processes."""
self._stop_processes(["acquisition", "data_preprocessor", "data_processor"])
self._kill_kamil_collectors()
def _spawn(self, name: str, command: list[str], *, allow_clean_exit: bool) -> None:
"""Spawn one process unless same process is already alive.
@@ -339,34 +331,6 @@ class ProcessSupervisor:
except (ProcessLookupError, PermissionError):
pass
@staticmethod
def _kill_kamil_collectors() -> None:
"""SIGKILL any Kamil ADC collector found by name — a guaranteed device backstop.
The collector survives a force-killed producer (own session) and can hang
the E-502, so it is hunted by cmdline and its group killed hard, regardless
of who its parent is. Best-effort and never raises.
"""
own_pid = os.getpid()
try:
pids = [int(entry.name) for entry in Path("/proc").iterdir() if entry.name.isdigit()]
except OSError:
return
killed = 0
for pid in pids:
if pid <= 1 or pid == own_pid:
continue
try:
cmdline = (Path("/proc") / str(pid) / "cmdline").read_bytes()
except OSError:
continue
executable = cmdline.split(b"\x00", 1)[0].rsplit(b"/", 1)[-1]
if executable == _KAMIL_COLLECTOR_MARKER:
ProcessSupervisor._signal_group(pid, signal.SIGKILL)
killed += 1
if killed:
logger.warning("Force-killed %d orphaned Kamil ADC collector process(es)", killed)
@staticmethod
def _log_abnormal_stop_exit(process: ManagedProcess) -> None:
"""Log a process that self-exited abnormally around stop time.
@@ -542,9 +506,6 @@ class ProcessSupervisor:
atomic_write_text(self._pidfile_path, "")
except OSError:
pass
# The ADC collector is a grandchild (spawned by the producer), not in the
# pidfile, so reap it separately by name.
self._kill_kamil_collectors()
def _is_stale_pipeline_pid(self, pid: int) -> bool:
"""Return whether `pid` still runs one of our pipeline binaries/scripts.
@@ -555,7 +516,7 @@ class ProcessSupervisor:
native_names = {"data_processor", "data_preprocessor"}
producer_modules = {
"python_app.scripts.matrix_raw_producer",
"python_app.scripts.kamil_adc_raw_producer",
"python_app.scripts.rph_radar_raw_producer",
}
try:
raw = (Path("/proc") / str(pid) / "cmdline").read_bytes()