/internal/storage/dolt: fix windows build issue

This commit is contained in:
Test
2026-01-21 13:59:47 -08:00
parent 0a9bcc2dd0
commit 7670112341
5 changed files with 91 additions and 27 deletions

View File

@@ -0,0 +1,15 @@
//go:build !windows
// +build !windows
package dolt
import (
"os/exec"
"syscall"
)
func setDoltServerSysProcAttr(cmd *exec.Cmd) {
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
}

View File

@@ -0,0 +1,12 @@
//go:build windows
// +build windows
package dolt
import "os/exec"
// Windows does not support Setpgid; leave default process attributes.
func setDoltServerSysProcAttr(cmd *exec.Cmd) {
// no-op
_ = cmd
}

View File

@@ -0,0 +1,32 @@
//go:build !windows
// +build !windows
package dolt
import (
"os"
"strings"
"syscall"
)
func processMayBeAlive(p *os.Process) bool {
// Signal 0 checks for existence without sending a real signal.
if err := p.Signal(syscall.Signal(0)); err != nil {
return false
}
return true
}
func terminateProcess(p *os.Process) error {
if p == nil {
return nil
}
if err := p.Signal(syscall.SIGTERM); err != nil {
// Process may already be dead; treat as success.
if strings.Contains(err.Error(), "process already finished") {
return nil
}
return err
}
return nil
}

View File

@@ -0,0 +1,21 @@
//go:build windows
// +build windows
package dolt
import "os"
func processMayBeAlive(p *os.Process) bool {
// Windows doesn't support Unix-style signal(0) checks. Treat as "unknown/alive"
// and let connection attempts / wait timeouts determine readiness.
_ = p
return true
}
func terminateProcess(p *os.Process) error {
if p == nil {
return nil
}
// Best-effort: Windows doesn't have SIGTERM semantics; kill the process.
return p.Kill()
}

View File

@@ -15,7 +15,6 @@ import (
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"syscall"
"time" "time"
) )
@@ -107,10 +106,8 @@ func (s *Server) Start(ctx context.Context) error {
s.cmd = exec.CommandContext(ctx, "dolt", args...) s.cmd = exec.CommandContext(ctx, "dolt", args...)
s.cmd.Dir = s.cfg.DataDir s.cmd.Dir = s.cfg.DataDir
// Set up process group for clean shutdown // Set up process group for clean shutdown (Unix-only; no-op on Windows).
s.cmd.SysProcAttr = &syscall.SysProcAttr{ setDoltServerSysProcAttr(s.cmd)
Setpgid: true,
}
// Set up logging // Set up logging
if s.cfg.LogFile != "" { if s.cfg.LogFile != "" {
@@ -163,13 +160,8 @@ func (s *Server) Stop() error {
return nil return nil
} }
// Try graceful shutdown first (SIGTERM) // Best-effort graceful shutdown (platform-specific).
if err := s.cmd.Process.Signal(syscall.SIGTERM); err != nil { _ = terminateProcess(s.cmd.Process)
// Process may already be dead
if !strings.Contains(err.Error(), "process already finished") {
return fmt.Errorf("failed to send SIGTERM: %w", err)
}
}
// Wait for graceful shutdown with timeout // Wait for graceful shutdown with timeout
done := make(chan error, 1) done := make(chan error, 1)
@@ -250,11 +242,9 @@ func (s *Server) waitForReady(ctx context.Context) error {
default: default:
} }
// Check if process is still alive using signal 0 // Best-effort: if we can tell the process is dead, fail fast.
if s.cmd.Process != nil { if s.cmd.Process != nil && !processMayBeAlive(s.cmd.Process) {
if err := s.cmd.Process.Signal(syscall.Signal(0)); err != nil { return fmt.Errorf("server process exited unexpectedly")
return fmt.Errorf("server process exited unexpectedly")
}
} }
// Try to connect // Try to connect
@@ -290,9 +280,8 @@ func GetRunningServerPID(dataDir string) int {
return 0 return 0
} }
// On Unix, FindProcess always succeeds, so we need to check if it's alive // Best-effort liveness check (platform-specific).
if err := process.Signal(syscall.Signal(0)); err != nil { if !processMayBeAlive(process) {
// Process is not running
_ = os.Remove(pidFile) _ = os.Remove(pidFile)
return 0 return 0
} }
@@ -307,13 +296,8 @@ func StopServerByPID(pid int) error {
return err return err
} }
// Try graceful shutdown first // Best-effort graceful shutdown (platform-specific).
if err := process.Signal(syscall.SIGTERM); err != nil { _ = terminateProcess(process)
if !strings.Contains(err.Error(), "process already finished") {
return err
}
return nil
}
// Wait for graceful shutdown // Wait for graceful shutdown
done := make(chan struct{}) done := make(chan struct{})