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
import contextlib
import os
import queue
import signal
import subprocess
import threading
from typing import Any
@@ -182,6 +184,7 @@ def start_ook() -> Response:
filtered_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
start_new_session=True,
)
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, '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)
app_module.ook_process = None

View File

@@ -125,7 +125,13 @@ var OokMode = (function () {
updateUI(false);
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 ----