fix: stop the trainer when the desktop engine quits - #4508
Conversation
|
@coderabbitai review |
|
/review |
Qodo reviews are paused for this user.Troubleshooting steps vary by plan Learn more → On a Teams plan? Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center? |
Greptile SummaryThe PR updates desktop-engine shutdown handling so an active fine-tuning process group is stopped before the engine exits.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains.
|
| Filename | Overview |
|---|---|
| src/praisonai-desktop/engine/server.py | The exit-signal handler now stops the active trainer before terminating the engine; no eligible blocking issue was identified. |
| src/praisonai-desktop/engine/test_train_routes.py | Adds POSIX integration coverage proving that an engine SIGTERM also terminates its active trainer. |
Sequence Diagram
sequenceDiagram
participant Desktop as Desktop shell
participant Engine as Python engine
participant Trainer as Trainer process group
Desktop->>Engine: SIGTERM
Engine->>Trainer: Trainer.stop()
Trainer-->>Engine: Termination requested
Engine->>Engine: sys.exit(0)
Reviews (2): Last reviewed commit: "fix: stop the trainer when the desktop e..." | Re-trigger Greptile
|
@claude You are the FINAL architecture reviewer. If the branch is under MervinPraison/PraisonAI (not a fork), you are able to make modifications to this branch and push directly. SCOPE: Review changes in this PR. Python SDK: praisonaiagents, praisonai. TypeScript SDK: src/praisonai-ts/. Do NOT modify src/praisonai-rust. Read ALL comments above from Gemini, Qodo, CodeRabbit, and Copilot carefully before responding. Phase 1: Review per AGENTS.md
Phase 2: FIX Valid Issues Phase 3: Final Verdict |
|
Claude finished @MervinPraison's task —— View job Final Architecture Review — PR #4508 ✅ APPROVE
Verdict: Approve. No code changes needed.Scope note: The change lives in Correctness — verified end to end
Robustness of the handler
Test quality
Reviewer feedback triage
Files modified by me: none — the PR is already correct and minimal. Job run • Branch |
|
@claude this PR has merge conflicts with |
|
Claude finished @MervinPraison's task —— View job Rebased PR #4508 onto latest
|
The trainer is spawned with start_new_session=True, so on macOS/Linux a signal aimed at the engine's process group never reaches it. The engine's exit handler was `lambda *_: sys.exit(0)`, which let the fine-tune reparent to init and keep the GPU with nothing left able to find or stop it. The exit handler now calls Trainer.stop() first, which terminates the trainer's own process group before the engine exits. Well within the 2s Engine::shutdown allows before SIGKILL. Co-authored-by: MervinPraison <MervinPraison@users.noreply.github.com>
747e3fe to
6d7df69
Compare
|
Merge gate scan — eligible for assessment. Claude merge gate will assess and may auto-merge if |
|
Merged by Claude PR merge gate ( |
Fixes #4491
Problem
On macOS/Linux, quitting the desktop app orphaned a running fine-tune. The trainer is spawned with
start_new_session=True(engine/training.py), so a signal aimed at the engine's process group never reaches it. The engine's exit handler wasregister_exit_signals(lambda *_: sys.exit(0))(engine/server.py), so on quit the engine simply exited, the trainer was reparented toinit(ppid 1), and it kept the GPU with nothing left able to find or stop it.Fix
The engine is the only process that knows the trainer's group. Its exit handler now calls
Trainer.stop()before exiting;Trainer.stop()→_terminate_groupalready SIGTERMs the trainer's own session/group. Sending one signal is well within the 2sEngine::shutdownallows before SIGKILL. Windows was already correct (taskkill /T) and is unaffected.Test
Added
QuitStopsTheTrainertoengine/test_train_routes.py(POSIX-only). It spawns a real engine, starts a run whose stub trainer records its pid then sleeps, sendsSIGTERMto the engine exactly as the Tauri shell does, and asserts the trainer pid is gone.the trainer (pid ...) outlived the engine quit) and passes with it.Minimal, backward-compatible; no new API surface.
Generated with Claude Code