Skip to content

Conversation

domenkozar
Copy link
Member

Prevents multiple process-compose instances from running simultaneously by checking PID file before starting. Handles stale PID files gracefully and replaces .expect() calls with proper error propagation using miette diagnostics.

Fixes #2198

Prevents multiple process-compose instances from running simultaneously by checking PID file before starting. Handles stale PID files gracefully and replaces .expect() calls with proper error propagation using miette diagnostics.

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

Co-Authored-By: Claude <[email protected]>
Copy link
Contributor

claude bot commented Oct 5, 2025

Claude finished @domenkozar's task —— View job


PR Review: Process Management Improvements

I've reviewed the process management improvements and have identified several areas for improvement:

Todo List:

  • Read and analyze the modified devenv.rs file
  • Review the test files for coverage
  • Identify potential bugs and security issues
  • Check performance considerations
  • Provide constructive feedback on improvements

Code Quality Issues

1. Race Condition in PID File Handling (devenv.rs:1085-1123)

The PID file check has a race condition between checking if the file exists and reading its contents:

if processes_pid_path.exists() {
    let existing_pid_str = fs::read_to_string(&processes_pid_path)
        .await
        .into_diagnostic()
        .wrap_err("Failed to read processes.pid file")?;

If the file is deleted between exists() and read_to_string(), this will fail. Consider using atomic file operations or handle the file not found error gracefully.

2. Inefficient Error Handling Pattern (devenv.rs:1093-1122)

The nested match statements for process checking could be simplified and made more robust:

  • The current code has three different behaviors for errors when checking processes
  • Consider consolidating error handling logic
  • The warning messages could be more consistent

3. Potential Security Issue with Signal Handling

The code uses signal::kill(pid, None) to check if a process exists, but doesn't validate that the PID belongs to a devenv process. A malicious or corrupted PID file could reference an unrelated system process.

4. Missing Error Context in Critical Paths

Several .expect() calls remain that should be replaced with proper error handling:

  • Line 1068: "Failed to write PROCESSES_SCRIPT"
  • Line 1072: "Failed to set permissions"
  • Line 1263: "Failed to remove PROCESSES_PID"

5. Inconsistent PID File Management

The PID file is written in two different places with different logic:

  • Detached mode: writes after spawning (line 1151)
  • Non-detached mode: writes before exec (line 1163)

This asymmetry could lead to inconsistent behavior and potential race conditions.

Performance Considerations

1. Blocking File I/O in Async Context

The code mixes tokio::fs and std::fs operations. Line 1133 uses std::fs::File::create() in an async context, which could block the async runtime.

2. Unnecessary String Allocations

Multiple .to_string() conversions could be avoided by using references where possible.

Suggestions for Improvement

1. Atomic PID File Operations

// Consider using a lock file or atomic write operations
let temp_pid_file = processes_pid_path.with_extension("tmp");
fs::write(&temp_pid_file, pid.to_string()).await?;
fs::rename(&temp_pid_file, &processes_pid_path).await?;

2. Process Ownership Validation

Store additional metadata in the PID file (process name, start time, etc.) to validate that the process is actually a devenv process.

3. Simplified Error Handling

Create a helper function for process state checking to reduce code duplication and improve consistency.

4. Better Test Coverage

The test only covers basic conflict detection. Consider adding tests for:

  • Stale PID file cleanup
  • Invalid PID values
  • Permission errors
  • Process termination edge cases

Security Concerns

1. TOCTOU (Time-of-Check-Time-of-Use) Vulnerabilities

The file existence check followed by read operations creates potential race conditions.

2. PID Reuse Issues

On busy systems, PIDs can be reused quickly. The current implementation doesn't account for process start times, which could lead to false positives.

Overall Assessment

The implementation addresses the core requirement of preventing multiple process-compose instances, but has several areas that could be improved for robustness, security, and maintainability. The test coverage is basic but functional.

The error handling improvements are good, but some .expect() calls remain that should be addressed for consistency with the PR's stated goals.

Copy link
Contributor

github-actions bot commented Oct 5, 2025

🔍 Suggested Reviewers

Based on git blame analysis of the changed lines, the following contributors have significant experience with the modified code:

  • @sandydoo - 100.0% of changed lines (7 lines)

Please consider reviewing this PR as you have authored significant portions of the code being modified. Your expertise would be valuable! 🙏

This comment was automatically generated by git-blame-auto-reviewer

Last updated: 2025-10-05T00:43:26.748Z

Copy link

Deploying devenv with  Cloudflare Pages  Cloudflare Pages

Latest commit: ee3c741
Status: ✅  Deploy successful!
Preview URL: https://3dd7810d.devenv.pages.dev
Branch Preview URL: https://improve-process-management.devenv.pages.dev

View logs

@domenkozar
Copy link
Member Author

This is trickier to solve in general case because we also need to support workflow when devenv up -d creates a detached mode and then devenv up should just attach.

@domenkozar
Copy link
Member Author

Let's do this only in detached mode: #2203

@domenkozar domenkozar closed this Oct 6, 2025
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.

devenv up -d overwrites pid file if processes are already running
1 participant