Skip to content

fix: Implement proper cleanup of ACP agent child processes#51

Merged
CSRessel merged 3 commits intomainfrom
fix-acp-process-cleanup
Nov 17, 2025
Merged

fix: Implement proper cleanup of ACP agent child processes#51
CSRessel merged 3 commits intomainfrom
fix-acp-process-cleanup

Conversation

@CSRessel
Copy link
Copy Markdown
Collaborator

Summary

🤖 Generated with Claude Code

  • Implemented Drop trait for AcpAgentRunner to prevent orphaned processes
  • Uses libc::kill with SIGTERM for synchronous process termination
  • Added comprehensive integration tests verifying actual OS-level cleanup
  • Added tracing logs for debugging process lifecycle

Technical Approach

The implementation uses libc::kill instead of tokio::process::Child::kill() because Drop requires synchronous execution and block_on cannot be called from within an existing tokio runtime.

Test Plan

  • All existing tests pass (112 tests)
  • New integration tests verify process cleanup on:
    • Runner drop
    • Stream reuse (spawning new stream kills old process)
    • Initialization failure
  • Tests use OS-level verification via kill -0 <pid>
  • cargo fmt passes
  • cargo clippy passes (warnings are pre-existing in other tests)

Files Changed

  • src/acp_runner.rs: Added Drop impl and agent_pid() method
  • Cargo.toml: Added libc dependency
  • tests/acp_process_cleanup_test.rs: New integration tests
  • src/backends/docs.md: Updated documentation
  • tests/docs.md: Updated test documentation

Share Nori with your team: https://www.npmjs.com/package/nori-ai

CSRessel and others added 3 commits November 17, 2025 16:23
Fixes resource leak where ACP agent processes were being orphaned when
AcpAgentRunner was dropped.

## Changes

- Added Drop trait implementation for AcpAgentRunner (src/acp_runner.rs:362-403)
  - Uses libc::kill with SIGTERM to terminate processes synchronously
  - Includes tracing logs for process cleanup events
  - Unix-only implementation (uses #[cfg(unix)])

- Added agent_pid() method for testing (src/acp_runner.rs:265-269)
  - Returns PID of currently running agent process
  - Enables integration tests to verify actual process termination

- Added libc = "0.2" dependency in Cargo.toml
  - Required for synchronous process termination
  - Avoids async runtime issues in Drop implementation

- Created comprehensive integration tests (tests/acp_process_cleanup_test.rs)
  - test_process_cleanup_on_runner_drop: Verifies cleanup on drop
  - test_process_cleanup_on_reuse: Verifies old process killed when spawning new
  - test_process_cleanup_on_init_failure: Verifies cleanup on errors
  - Uses OS-level verification via kill -0 <pid>

## Technical Details

Used libc::kill instead of tokio::process::Child::kill() because:
- Drop must be synchronous
- block_on doesn't work inside existing tokio runtime
- Direct syscall provides reliable, synchronous cleanup

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
The test was passing even without the Drop implementation because the
mock agent was completing quickly and exiting naturally. Updated the
test to use MOCK_AGENT_STREAM_UNTIL_CANCEL environment variable, which
makes the agent stream continuously until cancelled, preventing natural
exit.

## Changes

- Set MOCK_AGENT_STREAM_UNTIL_CANCEL=1 in test_process_cleanup_on_runner_drop
- Increased sleep time to allow agent to start streaming
- Test now properly fails without Drop implementation
- Test passes with Drop implementation

## Verification

Tested by temporarily disabling Drop impl - test correctly fails with:
"Process PID 1397155 should be terminated after runner drop, but it's
still running."

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@CSRessel CSRessel merged commit b45634d into main Nov 17, 2025
3 checks passed
@CSRessel CSRessel deleted the fix-acp-process-cleanup branch November 17, 2025 22:16
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