feat: implement isolated model worker with auto-restart and hot-reload
Introduce a supervised child process for capture, VAD, and recognition, enabling automatic restart on crash/hang and hot-reload via SIGHUP. Add `--model-auto-restart`, `--model-timeout`, and `--model-shutdown-timeout` options. Refactor `Run()` with lifecycle hooks for proper process group cleanup. Update README with new behavior and CLI flags.
This commit is contained in:
@@ -50,6 +50,14 @@ Final captions use stdout; diagnostics and overload warnings use stderr. This ma
|
||||
|
||||
Press <kbd>Ctrl</kbd>+<kbd>C</kbd> to stop. Captioneer stops `parec` and flushes pending audio before exiting.
|
||||
|
||||
Sherpa recognition, Silero VAD, and audio capture run in an isolated worker process. The terminal or GTK process stays responsive if native inference crashes or hangs: Captioneer restarts the worker automatically after a failure, and Ctrl+C force-kills only that worker if it cannot flush within the configured shutdown timeout. Send `SIGHUP` to the parent Captioneer PID to hot-reload the models without closing the terminal or overlay:
|
||||
|
||||
```bash
|
||||
kill -HUP <captioneer-parent-pid>
|
||||
```
|
||||
|
||||
An automatic or manual restart begins a fresh capture/transcription session; audio being processed by the failed worker cannot be recovered.
|
||||
|
||||
## Desktop overlay
|
||||
|
||||
The simplest Bazzite development command is:
|
||||
@@ -98,6 +106,9 @@ Layer Shell and X11 hints are requests, not universal guarantees. Same-layer win
|
||||
| `--models-dir=models` | `models` | Directory containing `parakeet-tdt-v2/` and `silero_vad_v5.onnx`. |
|
||||
| `--threads=2` | `2` | CPU threads used by recognition and VAD. |
|
||||
| `--preview-threshold-dbfs=-45` | `-45` | RMS threshold that starts a provisional VAD caption. Raise it to reject background audio; lower it for quiet speech. |
|
||||
| `--model-auto-restart=true` | `true` | Restart the isolated model worker after a crash, capture failure, or timeout. Set `false` to report the failure and exit instead. |
|
||||
| `--model-timeout=30s` | `30s` | Maximum model startup, continuously busy processing time, or missing-heartbeat period before the worker is considered hung. `0s` disables hang detection. |
|
||||
| `--model-shutdown-timeout=2s` | `2s` | Time allowed for pending-audio flush and model cleanup after Ctrl+C or reload before the worker is force-killed. |
|
||||
|
||||
### Desktop-only options
|
||||
|
||||
@@ -166,10 +177,11 @@ Captioneer itself has no environment-based application configuration; use the co
|
||||
- **Overlay is not always above other windows:** read the backend warning. On Wayland this usually means the compositor lacks Layer Shell; add a compositor rule for the `Captioneer Overlay` window if supported.
|
||||
- **Overlay initialization fails:** `--output=overlay` exits with the error. `--output=both` warns and continues terminal-only.
|
||||
- **A locally built desktop binary misses shared libraries:** use `scripts/distrobox/run.sh` or install the matching GTK4 and GTK4 Layer Shell runtime packages. The desktop command in a published release carries these application libraries in its private `lib/` directory; keep the extracted directory together.
|
||||
- **The model worker repeatedly restarts:** inspect the warning on stderr. Slow machines may need a larger `--model-timeout`; use `--model-auto-restart=false` when diagnosing a persistent crash so Captioneer exits on the first failure.
|
||||
|
||||
## Development
|
||||
|
||||
The transcription pipeline emits presentation-neutral events. `output/terminal` and `output/overlay` consume those events independently; GTK stays on its main OS thread while capture and recognition run on a worker.
|
||||
The transcription pipeline emits presentation-neutral events. `output/terminal` and `output/overlay` consume those events independently; GTK stays on its main OS thread while capture, VAD, and recognition run in a supervised child process. Caption events and health messages cross a private pipe, and the child is placed in its own process group so its `parec` process can be stopped or replaced with it.
|
||||
|
||||
```text
|
||||
src/app/ capture/model/process lifecycle
|
||||
|
||||
Reference in New Issue
Block a user