fix temporal build for windows (#3045)

This commit is contained in:
Max Novich
2025-06-23 17:45:26 -07:00
committed by GitHub
parent 603d0da27c
commit e6a893254d
7 changed files with 71 additions and 26 deletions

View File

@@ -24,10 +24,10 @@ fi
echo "Compiling Go binary..." echo "Compiling Go binary..."
if [ -n "${GOOS:-}" ] && [ -n "${GOARCH:-}" ]; then if [ -n "${GOOS:-}" ] && [ -n "${GOARCH:-}" ]; then
echo "Cross-compiling for ${GOOS}/${GOARCH}..." echo "Cross-compiling for ${GOOS}/${GOARCH}..."
GOOS="${GOOS}" GOARCH="${GOARCH}" go build -o "${BINARY_NAME}" . GOOS="${GOOS}" GOARCH="${GOARCH}" go build -buildvcs=false -o "${BINARY_NAME}" .
else else
echo "Building for current platform..." echo "Building for current platform..."
go build -o "${BINARY_NAME}" . go build -buildvcs=false -o "${BINARY_NAME}" .
fi fi
# Make it executable (skip on Windows as it's not needed) # Make it executable (skip on Windows as it's not needed)

View File

@@ -11,7 +11,6 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"strings" "strings"
"syscall"
"time" "time"
"go.temporal.io/sdk/activity" "go.temporal.io/sdk/activity"
@@ -158,9 +157,7 @@ func executeBackgroundJobWithCancellation(ctx context.Context, jobID, recipePath
) )
// Set up process group for proper cleanup // Set up process group for proper cleanup
cmd.SysProcAttr = &syscall.SysProcAttr{ configureSysProcAttr(cmd)
Setpgid: true, // Create new process group
}
// Set up environment // Set up environment
cmd.Env = append(os.Environ(), cmd.Env = append(os.Environ(),
@@ -278,9 +275,7 @@ func executeForegroundJobCLIWithCancellation(ctx context.Context, jobID string,
) )
// Set up process group for proper cleanup // Set up process group for proper cleanup
cmd.SysProcAttr = &syscall.SysProcAttr{ configureSysProcAttr(cmd)
Setpgid: true, // Create new process group
}
// Set up environment // Set up environment
cmd.Env = append(os.Environ(), cmd.Env = append(os.Environ(),

View File

@@ -253,10 +253,7 @@ func ensureTemporalServerRunning(ports *PortConfig) error {
cmd := exec.Command(temporalCmd, args...) cmd := exec.Command(temporalCmd, args...)
// Properly detach the process so it survives when the parent exits // Properly detach the process so it survives when the parent exits
cmd.SysProcAttr = &syscall.SysProcAttr{ configureSysProcAttr(cmd)
Setpgid: true, // Create new process group
Pgid: 0, // Use process ID as group ID
}
// Redirect stdin/stdout/stderr to avoid hanging // Redirect stdin/stdout/stderr to avoid hanging
cmd.Stdin = nil cmd.Stdin = nil

View File

@@ -131,26 +131,20 @@ func killProcessGroup(process *os.Process) error {
switch runtime.GOOS { switch runtime.GOOS {
case "windows": case "windows":
// On Windows, kill the process tree // On Windows, kill the process tree
cmd := exec.Command("taskkill", "/F", "/T", "/PID", fmt.Sprintf("%d", pid)) return killProcessGroupByPID(pid, 0) // signal parameter not used on Windows
if err := cmd.Run(); err != nil {
log.Printf("Failed to kill Windows process tree for PID %d: %v", pid, err)
return err
}
log.Printf("Successfully killed Windows process tree for PID %d", pid)
return nil
default: default:
// On Unix-like systems, kill the process group more aggressively // On Unix-like systems, kill the process group more aggressively
log.Printf("Killing Unix process group for PID %d", pid) log.Printf("Killing Unix process group for PID %d", pid)
// First, try to kill the entire process group with SIGTERM // First, try to kill the entire process group with SIGTERM
if err := syscall.Kill(-pid, syscall.SIGTERM); err != nil { if err := killProcessGroupByPID(pid, syscall.SIGTERM); err != nil {
log.Printf("Failed to send SIGTERM to process group -%d: %v", pid, err) log.Printf("Failed to send SIGTERM to process group -%d: %v", pid, err)
} else { } else {
log.Printf("Sent SIGTERM to process group -%d", pid) log.Printf("Sent SIGTERM to process group -%d", pid)
} }
// Also try to kill the main process directly // Also try to kill the main process directly
if err := syscall.Kill(pid, syscall.SIGTERM); err != nil { if err := killProcessByPID(pid, syscall.SIGTERM); err != nil {
log.Printf("Failed to send SIGTERM to process %d: %v", pid, err) log.Printf("Failed to send SIGTERM to process %d: %v", pid, err)
} else { } else {
log.Printf("Sent SIGTERM to process %d", pid) log.Printf("Sent SIGTERM to process %d", pid)
@@ -160,14 +154,14 @@ func killProcessGroup(process *os.Process) error {
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
// Force kill the process group with SIGKILL // Force kill the process group with SIGKILL
if err := syscall.Kill(-pid, syscall.SIGKILL); err != nil { if err := killProcessGroupByPID(pid, syscall.SIGKILL); err != nil {
log.Printf("Failed to send SIGKILL to process group -%d: %v", pid, err) log.Printf("Failed to send SIGKILL to process group -%d: %v", pid, err)
} else { } else {
log.Printf("Sent SIGKILL to process group -%d", pid) log.Printf("Sent SIGKILL to process group -%d", pid)
} }
// Force kill the main process with SIGKILL // Force kill the main process with SIGKILL
if err := syscall.Kill(pid, syscall.SIGKILL); err != nil { if err := killProcessByPID(pid, syscall.SIGKILL); err != nil {
log.Printf("Failed to send SIGKILL to process %d: %v", pid, err) log.Printf("Failed to send SIGKILL to process %d: %v", pid, err)
} else { } else {
log.Printf("Sent SIGKILL to process %d", pid) log.Printf("Sent SIGKILL to process %d", pid)
@@ -229,7 +223,7 @@ func FindAndKillProcessesByPattern(jobID string) int {
log.Printf("Found process %d matching pattern '%s' for job %s", pid, pattern, jobID) log.Printf("Found process %d matching pattern '%s' for job %s", pid, pattern, jobID)
// Kill the process // Kill the process
if err := syscall.Kill(pid, syscall.SIGTERM); err != nil { if err := killProcessByPID(pid, syscall.SIGTERM); err != nil {
log.Printf("Failed to send SIGTERM to PID %d: %v", pid, err) log.Printf("Failed to send SIGTERM to PID %d: %v", pid, err)
} else { } else {
log.Printf("Sent SIGTERM to PID %d", pid) log.Printf("Sent SIGTERM to PID %d", pid)
@@ -238,7 +232,7 @@ func FindAndKillProcessesByPattern(jobID string) int {
// Wait a moment then force kill // Wait a moment then force kill
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
if err := syscall.Kill(pid, syscall.SIGKILL); err != nil { if err := killProcessByPID(pid, syscall.SIGKILL); err != nil {
log.Printf("Failed to send SIGKILL to PID %d: %v", pid, err) log.Printf("Failed to send SIGKILL to PID %d: %v", pid, err)
} else { } else {
log.Printf("Sent SIGKILL to PID %d", pid) log.Printf("Sent SIGKILL to PID %d", pid)

View File

@@ -0,0 +1,27 @@
//go:build !windows
// +build !windows
package main
import (
"os/exec"
"syscall"
)
// configureSysProcAttr configures the SysProcAttr for Unix-like systems
func configureSysProcAttr(cmd *exec.Cmd) {
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, // Create new process group
Pgid: 0, // Use process ID as group ID
}
}
// killProcessByPID kills a process using Unix syscalls
func killProcessByPID(pid int, signal syscall.Signal) error {
return syscall.Kill(pid, signal)
}
// killProcessGroupByPID kills a process group using Unix syscalls
func killProcessGroupByPID(pid int, signal syscall.Signal) error {
return syscall.Kill(-pid, signal)
}

View File

@@ -0,0 +1,32 @@
//go:build windows
// +build windows
package main
import (
"fmt"
"os/exec"
"syscall"
)
// configureSysProcAttr configures the SysProcAttr for Windows
func configureSysProcAttr(cmd *exec.Cmd) {
// Windows doesn't support Setpgid/Pgid, so we use different approach
cmd.SysProcAttr = &syscall.SysProcAttr{
CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
}
}
// killProcessByPID kills a process on Windows
func killProcessByPID(pid int, signal syscall.Signal) error {
// On Windows, we use taskkill command instead of syscall.Kill
cmd := exec.Command("taskkill", "/F", "/PID", fmt.Sprintf("%d", pid))
return cmd.Run()
}
// killProcessGroupByPID kills a process group on Windows
func killProcessGroupByPID(pid int, signal syscall.Signal) error {
// On Windows, kill the process tree
cmd := exec.Command("taskkill", "/F", "/T", "/PID", fmt.Sprintf("%d", pid))
return cmd.Run()
}

Binary file not shown.