Skip to content

Conversation

@mostlygeek
Copy link
Owner

@mostlygeek mostlygeek commented May 16, 2025

Ref: #130

  • Add a new cmdStop configuration option for models.
  • Make the cmdStop on windows default to taskkill /f /t /p ${PID}
  • Remove windows/non-windows specific Process.terminateProcess() functions
  • Keep the timeout to send a Kill

Where this might be useful:

  • container systems like podman/docker. The cmdStop can be podman kill my-container or docker stop my-container
  • some other specific logic for stopping a process

Summary by CodeRabbit

  • New Features
    • Added support for specifying a custom stop command for models, including a default stop command for Windows systems.
  • Bug Fixes
    • Improved process termination to use custom stop commands when configured, with fallback to standard termination signals.
  • Tests
    • Added tests verifying assignment and execution of custom stop commands, including Windows-specific behavior.
  • Chores
    • Removed legacy process termination code replaced by the new stop command logic.

@coderabbitai
Copy link

coderabbitai bot commented May 16, 2025

Walkthrough

A new CmdStop field was added to the ModelConfig struct to support custom stop commands for process management. The configuration loader now sets a default Windows stop command if none is provided. The process termination logic was updated to use this field, and platform-specific termination helper files were removed. New tests verify the correct assignment and usage of the CmdStop field.

Changes

File(s) Change Summary
proxy/config.go Added CmdStop field to ModelConfig; updated config loader to set default Windows stop command if CmdStop is empty.
proxy/config_windows_test.go Removed trailing blank line in test; no functional changes.
proxy/process.go Updated Process.stopCommand to use custom stop command from CmdStop if specified, otherwise fall back to SIGTERM logic; added Windows default stop command logic.
proxy/process_stop.go, proxy/process_stop_windows.go Removed platform-specific terminateProcess helper functions and related logic.
proxy/process_test.go Added test to verify process termination uses custom CmdStop command when provided.
README.md Extended documentation to include new optional cmdStop field for custom stop commands in model config.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ConfigLoader
    participant ModelConfig
    participant Process

    User->>ConfigLoader: Load configuration
    ConfigLoader->>ModelConfig: Initialize ModelConfig
    alt OS is Windows and CmdStop is empty
        ModelConfig->>ModelConfig: Set CmdStop to default Windows stop command
    end
    ConfigLoader->>Process: Pass ModelConfig

    User->>Process: Start process
    Process->>Process: Run command

    User->>Process: StopImmediately()
    alt CmdStop is set
        Process->>Process: Replace ${PID} in CmdStop
        Process->>Process: Execute stop command
    else
        Process->>Process: Send SIGTERM to process
    end
Loading
sequenceDiagram
    participant Test
    participant ConfigLoader
    participant ModelConfig
    participant Process

    Test->>ConfigLoader: Load config with custom CmdStop
    ConfigLoader->>ModelConfig: Assign CmdStop from config
    ConfigLoader->>Process: Pass ModelConfig

    Test->>Process: Start()
    Process->>Process: Process starts

    Test->>Process: StopImmediately()
    Process->>Process: Use custom CmdStop for termination
    Process->>Test: State transitions to Stopped
Loading

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.


Note

⚡️ Faster reviews with caching

CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure Review - Disable Cache at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the Data Retention setting under your Organization Settings.
Enjoy the performance boost—your workflow just got faster.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 9a1069f and 3345ddb.

📒 Files selected for processing (4)
  • README.md (1 hunks)
  • proxy/config.go (3 hunks)
  • proxy/config_windows_test.go (0 hunks)
  • proxy/process.go (2 hunks)
💤 Files with no reviewable changes (1)
  • proxy/config_windows_test.go
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • proxy/config.go
  • proxy/process.go
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@mostlygeek mostlygeek self-assigned this May 16, 2025
@mostlygeek mostlygeek added the enhancement New feature or request label May 16, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
proxy/process.go (1)

403-405: Clean up commented-out code.

Remove the commented-out code as it's no longer needed and is being replaced with the new implementation below.

-	// if err := p.terminateProcess(); err != nil {
-	// 	p.proxyLogger.Debugf("<%s> Process already terminated: %v (normal during shutdown)", p.ID, err)
-	// }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between f9ee715 and cf4808d.

📒 Files selected for processing (6)
  • proxy/config.go (3 hunks)
  • proxy/config_windows_test.go (2 hunks)
  • proxy/process.go (1 hunks)
  • proxy/process_stop.go (0 hunks)
  • proxy/process_stop_windows.go (0 hunks)
  • proxy/process_test.go (1 hunks)
💤 Files with no reviewable changes (2)
  • proxy/process_stop.go
  • proxy/process_stop_windows.go
🧰 Additional context used
🧬 Code Graph Analysis (3)
proxy/process_test.go (1)
proxy/process.go (4)
  • NewProcess (78-106)
  • StateReady (23-23)
  • StopImmediately (36-36)
  • StateStopped (21-21)
proxy/config_windows_test.go (1)
proxy/config.go (1)
  • LoadConfigFromReader (104-192)
proxy/process.go (1)
proxy/config.go (1)
  • SanitizeCommand (239-272)
🪛 GitHub Actions: Windows CI
proxy/process_test.go

[error] 60-60: TestProcess_AutomaticallyStartsUpstream failed: Expected status code 200, got 502. Also, failed to send SIGTERM to process: not supported by windows.


[error] 437-437: TestProcess_ForceStopWithKill failed: Expected error message containing 'wsarecv: An existing connection was forcibly closed by the remote host' but got '12345'. Failed to send SIGTERM to process: not supported by windows.


[error] 1-1: TestProcess_StopCmd encountered error: 'kill: 3364: No such process' and failed to exec stop command with exit status 1.

proxy/config_windows_test.go

[error] 52-53: TestConfig_WindowsCmdStopIsSet failed due to YAML parsing error: 'yaml: line 2: found character that cannot start any token'. Also, expected command 'taskkill /f /t /pid ${PID}' was not found.

🔇 Additional comments (4)
proxy/config.go (2)

20-20: Good addition of the new CmdStop field.

The new field allows configuring custom stop commands for different platforms, which aligns with the PR objective of adding a stopCmd to model configuration.


163-168: Good implementation of Windows-specific default stop command.

Setting a default Windows stop command if none is provided is a great approach that ensures Windows systems have a platform-appropriate termination method. The taskkill /f /t /pid ${PID} command is correctly used to forcibly terminate processes and their child processes on Windows.

proxy/process.go (2)

407-426: Well-implemented custom stop command execution.

This is a good implementation that:

  1. Replaces the placeholder with the actual PID
  2. Properly sanitizes the command
  3. Sets up output redirection
  4. Handles execution errors

This flexible approach allows for platform-specific termination commands.


427-431:

❓ Verification inconclusive

Handle Windows-specific signal limitations.

The SIGTERM fallback won't work on Windows (error: Failed to send SIGTERM to process: not supported by windows), but this code path should rarely be taken on Windows since a default stop command is set during config loading.

Consider adding a runtime check to handle Windows differently:

} else {
+	if runtime.GOOS == "windows" {
+		p.proxyLogger.Errorf("<%s> No CmdStop defined and SIGTERM not supported on Windows", p.ID)
+		// Fall back to Kill as last resort
+		p.upstreamWasStoppedWithKill = true
+		if err := p.cmd.Process.Kill(); err != nil {
+			p.proxyLogger.Errorf("<%s> Failed to kill process: %v", p.ID, err)
+		}
+		return
+	}
	if err := p.cmd.Process.Signal(syscall.SIGTERM); err != nil {
		p.proxyLogger.Errorf("<%s> Failed to send SIGTERM to process: %v", p.ID, err)
		return
	}
}

Let's verify how frequently this code path might be hit on Windows:


🏁 Script executed:

#!/bin/bash
# Check if there are any cases where a ModelConfig on Windows could have empty CmdStop

# Look for any test code that creates ModelConfig without setting CmdStop
rg "ModelConfig\s*{\s*[^}]*\s*}" --type go | grep -v "CmdStop"

# Look for any code that directly modifies CmdStop to empty
rg "config.*CmdStop\s*=\s*\"\"" --type go

Length of output: 229


proxy/process.go (lines 427–431): Add Windows‐specific fallback for process termination

Snippet showing current state:

		if err := p.cmd.Process.Signal(syscall.SIGTERM); err != nil {
			p.proxyLogger.Errorf("<%s> Failed to send SIGTERM to process: %v", p.ID, err)
			return
		}
	}

Handle Windows‐specific signal limitations. On Windows SIGTERM is unsupported, so we should detect runtime.GOOS == "windows" and fall back to Kill:

} else {
+   if runtime.GOOS == "windows" {
+       p.proxyLogger.Errorf("<%s> No CmdStop defined and SIGTERM not supported on Windows", p.ID)
+       p.upstreamWasStoppedWithKill = true
+       if err := p.cmd.Process.Kill(); err != nil {
+           p.proxyLogger.Errorf("<%s> Failed to kill process: %v", p.ID, err)
+       }
+       return
+   }
    if err := p.cmd.Process.Signal(syscall.SIGTERM); err != nil {
        p.proxyLogger.Errorf("<%s> Failed to send SIGTERM to process: %v", p.ID, err)
        return
    }
}

Verification attempt:

rg 'ModelConfig\s*{\s*[^}]*}' --type go | grep -v 'CmdStop'
rg 'config.*CmdStop\s*=\s*""' --type go

The first command failed due to regex parsing issues, so we could not confirm automatically whether any ModelConfig ever omits CmdStop. Please manually verify that every config on Windows has a non‐empty CmdStop, or apply this fallback to guard against the rare case where it does not.

@mostlygeek mostlygeek merged commit a8b81f2 into main May 16, 2025
2 of 3 checks passed
@mostlygeek mostlygeek deleted the cmd-stop branch May 16, 2025 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants