refactor: Extract processExists to util.ProcessExists (gt-560ge)
Move duplicated processExists function to shared util package: - Create internal/util/process.go with ProcessExists function - Add internal/util/process_test.go with basic tests - Update witness/manager.go to use util.ProcessExists - Update refinery/manager.go to use util.ProcessExists - Remove local processExists functions from both files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -113,7 +113,7 @@ func (m *Manager) Start(foreground bool) error {
|
||||
if foreground {
|
||||
// In foreground mode, we're likely running inside the tmux session
|
||||
// that background mode created. Only check PID to avoid self-detection.
|
||||
if ref.State == StateRunning && ref.PID > 0 && processExists(ref.PID) {
|
||||
if ref.State == StateRunning && ref.PID > 0 && util.ProcessExists(ref.PID) {
|
||||
return ErrAlreadyRunning
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ func (m *Manager) Start(foreground bool) error {
|
||||
}
|
||||
|
||||
// Also check via PID for backwards compatibility
|
||||
if ref.State == StateRunning && ref.PID > 0 && processExists(ref.PID) {
|
||||
if ref.State == StateRunning && ref.PID > 0 && util.ProcessExists(ref.PID) {
|
||||
return ErrAlreadyRunning
|
||||
}
|
||||
|
||||
@@ -224,7 +224,7 @@ func (m *Manager) Stop() error {
|
||||
}
|
||||
|
||||
// If we have a PID and it's a different process, try to stop it gracefully
|
||||
if ref.PID > 0 && ref.PID != os.Getpid() && processExists(ref.PID) {
|
||||
if ref.PID > 0 && ref.PID != os.Getpid() && util.ProcessExists(ref.PID) {
|
||||
// Send SIGTERM (best-effort graceful stop)
|
||||
if proc, err := os.FindProcess(ref.PID); err == nil {
|
||||
_ = proc.Signal(os.Interrupt)
|
||||
@@ -638,16 +638,6 @@ func (m *Manager) pushWithRetry(targetBranch string, config MergeConfig) error {
|
||||
return fmt.Errorf("push failed after %d retries: %v", config.PushRetryCount, lastErr)
|
||||
}
|
||||
|
||||
// processExists checks if a process with the given PID exists.
|
||||
func processExists(pid int) bool {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// On Unix, FindProcess always succeeds; signal 0 tests existence
|
||||
err = proc.Signal(nil)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// formatAge formats a duration since the given time.
|
||||
func formatAge(t time.Time) string {
|
||||
|
||||
13
internal/util/process.go
Normal file
13
internal/util/process.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package util
|
||||
|
||||
import "os"
|
||||
|
||||
// ProcessExists checks if a process with the given PID exists.
|
||||
// It uses the Unix convention of sending signal 0 to test for process existence.
|
||||
func ProcessExists(pid int) bool {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
return proc.Signal(nil) == nil
|
||||
}
|
||||
25
internal/util/process_test.go
Normal file
25
internal/util/process_test.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestProcessExistsNonExistent(t *testing.T) {
|
||||
// Using a very high PID that's unlikely to exist
|
||||
pid := 999999999
|
||||
if ProcessExists(pid) {
|
||||
t.Errorf("ProcessExists(%d) = true, want false for non-existent process", pid)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProcessExistsNegativePID(t *testing.T) {
|
||||
// Negative PIDs are invalid and should return false or may cause errors
|
||||
// depending on the platform, so just test that it doesn't panic
|
||||
_ = ProcessExists(-1)
|
||||
}
|
||||
|
||||
func TestProcessExistsZero(t *testing.T) {
|
||||
// PID 0 is special (kernel process on Unix)
|
||||
// Test that we can call it without panicking
|
||||
_ = ProcessExists(0)
|
||||
}
|
||||
@@ -90,7 +90,7 @@ func (m *Manager) Start() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if w.State == StateRunning && w.PID > 0 && processExists(w.PID) {
|
||||
if w.State == StateRunning && w.PID > 0 && util.ProcessExists(w.PID) {
|
||||
return ErrAlreadyRunning
|
||||
}
|
||||
|
||||
@@ -128,13 +128,3 @@ func (m *Manager) Stop() error {
|
||||
return m.saveState(w)
|
||||
}
|
||||
|
||||
// processExists checks if a process with the given PID exists.
|
||||
func processExists(pid int) bool {
|
||||
proc, err := os.FindProcess(pid)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
// On Unix, FindProcess always succeeds; signal 0 tests existence
|
||||
err = proc.Signal(nil)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user