Skip to content

fix(apps): cleanup orphaned app processes on daemon restart#818

Open
realkim93 wants to merge 3 commits into
pollen-robotics:mainfrom
realkim93:fix/cleanup-orphaned-app-processes
Open

fix(apps): cleanup orphaned app processes on daemon restart#818
realkim93 wants to merge 3 commits into
pollen-robotics:mainfrom
realkim93:fix/cleanup-orphaned-app-processes

Conversation

@realkim93
Copy link
Copy Markdown

Summary

  • When the daemon restarts, app subprocesses spawned by the previous AppManager remain running as orphans
  • The new daemon's AppManager initializes with current_app = None, unaware of these orphans
  • Both the orphaned app and the new daemon send commands to the robot simultaneously, causing conflicts

This PR adds _cleanup_orphaned_apps() to AppManager.__init__() that detects and terminates orphaned app processes on startup.

Detection criteria (all must match)

  • Executable path is under _get_venv_parent_dir()
  • Matches *_venv/bin/python pattern (.venv excluded to protect the daemon itself)
  • Command line contains -m (module execution pattern)
  • PID is not the current daemon or any of its children

Termination strategy

  1. SIGTERM for graceful shutdown (3-second timeout)
  2. _kill_process_tree() + kill() for force termination of survivors

Changes

  • src/reachy_mini/apps/manager.py: Added _cleanup_orphaned_apps() method + 1-line call in __init__

Test plan

  • Start daemon → start an app → restart daemon only → verify orphaned process is cleaned up
  • Verify daemon's own process is not falsely terminated
  • Verify no errors when no orphaned processes exist

🤖 Generated with Claude Code

realkim93 and others added 2 commits February 11, 2026 23:09
When the daemon restarts, app subprocesses from the previous session
may still be running as orphans. The new AppManager now detects and
terminates them during initialization to prevent conflicting robot
commands.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
psutil.exe() resolves symlinks, losing the original venv path. Fall
back to cmdline[0] which preserves the invocation path and correctly
matches *_venv/bin/python patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@realkim93
Copy link
Copy Markdown
Author

Test Results

Tested locally on macOS (Darwin 25.2.0, Python 3.12.9).

Test 1: Orphaned app process cleanup

  • Spawned a fake orphan process (*_venv/bin/python -m http.server) under the venv parent directory, detached from the current process tree via start_new_session=True
  • Instantiated AppManager_cleanup_orphaned_apps() detected and terminated the orphan via SIGTERM
  • PASS

Test 2: Daemon self-protection

  • Instantiated AppManager and verified the current process (simulating the daemon) was NOT terminated
  • .venv exclusion rule correctly protected the daemon's own process
  • PASS

Test 3: No orphans — no errors

  • Instantiated AppManager with no orphaned processes running
  • Initialization completed without errors, current_app correctly set to None
  • PASS

Note on second commit

During testing, discovered that psutil.exe() resolves symlinks (e.g., venv/bin/python/usr/bin/python3.12), which caused the path-based detection to miss orphans. Fixed by also checking cmdline[0], which preserves the original invocation path.

Check for both bin/ (Linux/macOS) and Scripts/ (Windows) when
matching app venv python executables.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@FabienDanieau FabienDanieau changed the base branch from develop to main March 3, 2026 14:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant