davsclaus opened a new pull request, #29811: URL: https://github.com/apache/camel/pull/29811
## Summary Fixes the first item of [CAMEL-26911](https://issues.apache.org/jira/browse/CAMEL-26911): **`camel stop` can kill an unrelated process.** The CLI treated any live pid that had a `~/.camel/<pid>-status.json` as a Camel integration. An integration that is killed (`kill -9`, `camel stop --kill`, the OOM killer) or crashes cannot remove its files. Once the OS hands its pid to another process, `camel ps` listed a ghost integration, and `camel stop <name>` (or `camel stop` for all) sent SIGTERM, or SIGKILL with `--kill`, to that other process. macOS pids wrap at 99999. ### Fix `ProcessHelper.isStale(ProcessHandle, Path)`: a status file that was last written before the process with that pid started cannot be its own, so it is left over and the pid is skipped. The check uses the start instant of the process from the OS and the modification time of the file, so it also works with integrations that run an older Camel version (nothing new in the status file). - 10 seconds of slack: the start instant is not exact on every OS (Linux computes it from clock ticks and a boot time in whole seconds), and a network file system may have a clock of its own. A pid is only reused after the pids wrap around, which takes far longer. - When either time is not known, the behaviour is as before. - Used where the CLI finds integrations: `ProcessFinder` (camel ps, stop, restart, log, trace, receive, cmd, the AI and MCP tools through `RuntimeHelper`) and `TuiHelper.findPids` (the TUI, including its stop actions). - The leftover files are not removed here: `PreviousRun.keepOrphans` reads the status file of a dead pid to keep its log for `camel log --previous`, and `camel dirty` cleans up. The other items of CAMEL-26911 (slow actions blocking stop, trace/receive clear, torn replies, log speed) follow in separate PRs. ### Before / after The unpacked launcher, a separate `user.home`, a `sleep 600` and a status file for its pid written an hour earlier: | | before | after | |---|---|---| | `camel ps` | lists `ghost` with the pid of the sleep | `No running Camel integrations` | | `camel stop ghost` | `Shutting down ... with SIGTERM`, sleep killed, exit 0 | `No running Camel integration matches: ghost`, exit 3, sleep alive | With the fixed jar, an integration started with `camel run --background` is still listed by `camel ps` and stopped by `camel stop tick` (exit 0), and once the status file of the sleep is written again it is listed again. ## Tests - `ProcessHelperTest.aFileWrittenBeforeItsProcessStartedIsStale`: older than the process, within the slack, newer, start unknown, no file. - `ProcessFinderTest.aStatusFileOlderThanItsProcessIsLeftOverAndFindsNothing`: a left-over status file finds nothing by name, pid or `*`, and a live integration is still found. - camel-jbang-core (2,878 tests) and camel-jbang-plugin-tui (2,570 tests) pass locally. _Claude Code on behalf of Claus Ibsen (davsclaus)_ 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_012nJsFsjqqFiwroeHRWaKbS -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
