fix(ook): use process group kill for reliable stop

The OOK subprocess was spawned without start_new_session=True, so
process.terminate() only signalled the parent — child processes kept
running. Now uses os.killpg() to terminate the entire process group,
matching the pattern used by all other routes (ADS-B, AIS, ACARS, etc.).

Also fixes silent error swallowing in the frontend stop handler so the
UI resets even if the backend request fails.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Smittix
2026-03-10 12:32:29 +00:00
parent fd12d11fab
commit e383575c80
2 changed files with 22 additions and 2 deletions

View File

@@ -8,7 +8,9 @@ PWM, PPM, and Manchester modulation with fully configurable pulse timing.
from __future__ import annotations from __future__ import annotations
import contextlib import contextlib
import os
import queue import queue
import signal
import subprocess import subprocess
import threading import threading
from typing import Any from typing import Any
@@ -182,6 +184,7 @@ def start_ook() -> Response:
filtered_cmd, filtered_cmd,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, stderr=subprocess.PIPE,
start_new_session=True,
) )
register_process(rtl_process) register_process(rtl_process)
@@ -278,7 +281,18 @@ def cleanup_ook(*, emit_status: bool = True) -> None:
_close_pipe(getattr(proc, 'stdout', None)) _close_pipe(getattr(proc, 'stdout', None))
_close_pipe(getattr(proc, 'stderr', None)) _close_pipe(getattr(proc, 'stderr', None))
safe_terminate(proc) # Kill the entire process group so child processes are cleaned up
try:
pgid = os.getpgid(proc.pid)
os.killpg(pgid, signal.SIGTERM)
try:
proc.wait(timeout=2)
except subprocess.TimeoutExpired:
os.killpg(pgid, signal.SIGKILL)
proc.wait(timeout=3)
except (ProcessLookupError, OSError):
# Process already dead — fall back to normal terminate
safe_terminate(proc)
unregister_process(proc) unregister_process(proc)
app_module.ook_process = None app_module.ook_process = None

View File

@@ -125,7 +125,13 @@ var OokMode = (function () {
updateUI(false); updateUI(false);
disconnectSSE(); disconnectSSE();
}) })
.catch(function () {}); .catch(function (err) {
console.error('Failed to stop OOK decoder:', err);
// Force UI reset even if backend call failed
state.running = false;
updateUI(false);
disconnectSSE();
});
} }
// ---- SSE ---- // ---- SSE ----