Skip to content

refactor(process): Improve subprocess signaling and lifecycle management - #6

Merged
ChristianPraiss merged 1 commit into
mainfrom
refactor/implement-advanced-signal-forwarding-for-subprocesses
Jul 28, 2026
Merged

refactor(process): Improve subprocess signaling and lifecycle management#6
ChristianPraiss merged 1 commit into
mainfrom
refactor/implement-advanced-signal-forwarding-for-subprocesses

Conversation

@ChristianPraiss

Copy link
Copy Markdown
Contributor

⚙️ Refactor(process): Improve Subprocess Signaling and Lifecycle Management

This pull request refactors how subprocesses are executed across key components (exec, main, and TUI) by implementing standardized, advanced signal forwarding logic.

✨ Motivation

Currently, graceful handling of signals upon process shutdown could be inconsistent. This change aims to align the component's behavior more closely with standard shell conventions for subprocess termination, ensuring a reliable user experience even when interrupts (like Ctrl+C) are issued.

🚀 Changes Implemented

The core change is the introduction and usage of runWithSignalForwarding. This function:

  1. Standardizes Termination: It ensures that when a process needs to shut down gracefully, it first attempts a soft termination via SIGINT (the signal typically caught by Ctrl+C).
  2. Improves Resilience: If multiple interruption signals occur, subsequent terminations fall back to a mandatory hard kill (kill()) for robust resource cleanup.
  3. Extends Coverage: This pattern is applied not only to standard processes but also extended within the TUI component (tui.go) to manage the dedicated lifecycle of panels and subprocesses consistently.

Technical Details:

  • The new signal flow improves reliability by clearly defining phases: graceful attempt $\rightarrow$ hard kill if needed.

✅ Verification & Testing

Please verify the following:

  • Subprocesses initiated from the main execution path correctly respond to single Ctrl+C interruptions (SIGINT).
  • Repeated interruption signals result in successful and timely cleanup using kill().
  • The TUI component maintains signal integrity when panels or internal subprocesses are terminated.

📚 Review Notes

  • This change is a critical structural refactor to the process handling layer, making our application more predictable during shutdowns.

Implements `runWithSignalForwarding` across exec, main, and TUI components. This enhances graceful shutdown by attempting SIGINT on the first interrupt (Ctrl+C), followed by a hard kill() for subsequent signals, aligning with standard shell conventions. The pattern is extended to manage subprocess lifecycles within the TUI component gracefully.
Copilot AI review requested due to automatic review settings July 28, 2026 13:53
@ChristianPraiss
ChristianPraiss merged commit 3b196fc into main Jul 28, 2026
3 checks passed
@ChristianPraiss
ChristianPraiss deleted the refactor/implement-advanced-signal-forwarding-for-subprocesses branch July 28, 2026 13:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Refactors subprocess execution to improve shutdown behavior by introducing centralized signal-handling logic and extending “graceful then force” termination semantics to the TUI’s panel subprocess lifecycle.

Changes:

  • Replaces direct cmd.Run() usage with a shared runWithSignalForwarding() helper for consistent SIGINT/SIGTERM handling and escalation behavior.
  • Enhances the TUI quit flow to first request graceful termination of running panels, then force-kill on repeated quit.
  • Tracks per-panel subprocess handles so the TUI can signal them on exit instead of leaving them running.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
tui.go Adds panel process tracking and a two-phase quit flow (graceful interrupt, then force kill) with updated status bar messaging.
main.go Switches the fallback docker compose <command> execution path to use runWithSignalForwarding().
exec.go Introduces runWithSignalForwarding() and applies it to subprocess execution paths (scripts and exec).
Comments suppressed due to low confidence (1)

exec.go:130

  • Forwarding SIGINT to cmd.Process here can double-deliver Ctrl+C to the child on Unix, because SIGINT is already sent by the terminal to the entire foreground process group (parent + child). Since we’re not creating a separate process group for cmd (no SysProcAttr.Setpgid usage in the repo), this means a single Ctrl+C can be seen twice by the child, defeating the intended “one Ctrl+C = graceful” behavior.
			case sig := <-sigCh:
				if !forwarded {
					forwarded = true
					_ = cmd.Process.Signal(sig)
				} else {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread exec.go
Comment on lines +112 to +115
func runWithSignalForwarding(cmd *exec.Cmd) error {
sigCh := make(chan os.Signal, 1)
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
defer signal.Stop(sigCh)
Comment thread tui.go
Comment on lines 243 to +247
case "q", "Q", "ctrl+c":
if m.running == 0 {
return m, tea.Quit
}
if !m.stopping {
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.

2 participants