Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions temporal-service/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ fi
echo "Compiling Go binary..."
if [ -n "${GOOS:-}" ] && [ -n "${GOARCH:-}" ]; then
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
echo "Building for current platform..."
go build -o "${BINARY_NAME}" .
go build -buildvcs=false -o "${BINARY_NAME}" .
fi

# Make it executable (skip on Windows as it's not needed)
Expand Down
9 changes: 2 additions & 7 deletions temporal-service/goose_workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"path/filepath"
"runtime"
"strings"
"syscall"
"time"

"go.temporal.io/sdk/activity"
Expand Down Expand Up @@ -158,9 +157,7 @@ func executeBackgroundJobWithCancellation(ctx context.Context, jobID, recipePath
)

// Set up process group for proper cleanup
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, // Create new process group
}
configureSysProcAttr(cmd)

// Set up environment
cmd.Env = append(os.Environ(),
Expand Down Expand Up @@ -278,9 +275,7 @@ func executeForegroundJobCLIWithCancellation(ctx context.Context, jobID string,
)

// Set up process group for proper cleanup
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, // Create new process group
}
configureSysProcAttr(cmd)

// Set up environment
cmd.Env = append(os.Environ(),
Expand Down
5 changes: 1 addition & 4 deletions temporal-service/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,7 @@ func ensureTemporalServerRunning(ports *PortConfig) error {
cmd := exec.Command(temporalCmd, args...)

// Properly detach the process so it survives when the parent exits
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true, // Create new process group
Pgid: 0, // Use process ID as group ID
}
configureSysProcAttr(cmd)

// Redirect stdin/stdout/stderr to avoid hanging
cmd.Stdin = nil
Expand Down
20 changes: 7 additions & 13 deletions temporal-service/process_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,26 +131,20 @@ func killProcessGroup(process *os.Process) error {
switch runtime.GOOS {
case "windows":
// On Windows, kill the process tree
cmd := exec.Command("taskkill", "/F", "/T", "/PID", fmt.Sprintf("%d", pid))
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
return killProcessGroupByPID(pid, 0) // signal parameter not used on Windows
default:
// On Unix-like systems, kill the process group more aggressively
log.Printf("Killing Unix process group for PID %d", pid)

// 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)
} else {
log.Printf("Sent SIGTERM to process group -%d", pid)
}

// 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)
} else {
log.Printf("Sent SIGTERM to process %d", pid)
Expand All @@ -160,14 +154,14 @@ func killProcessGroup(process *os.Process) error {
time.Sleep(1 * time.Second)

// 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)
} else {
log.Printf("Sent SIGKILL to process group -%d", pid)
}

// 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)
} else {
log.Printf("Sent SIGKILL to process %d", pid)
Expand Down Expand Up @@ -229,7 +223,7 @@ func FindAndKillProcessesByPattern(jobID string) int {
log.Printf("Found process %d matching pattern '%s' for job %s", pid, pattern, jobID)

// 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)
} else {
log.Printf("Sent SIGTERM to PID %d", pid)
Expand All @@ -238,7 +232,7 @@ func FindAndKillProcessesByPattern(jobID string) int {

// Wait a moment then force kill
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)
} else {
log.Printf("Sent SIGKILL to PID %d", pid)
Expand Down
27 changes: 27 additions & 0 deletions temporal-service/syscall_unix.go
Original file line number Diff line number Diff line change
@@ -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)
}
32 changes: 32 additions & 0 deletions temporal-service/syscall_windows.go
Original file line number Diff line number Diff line change
@@ -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 modified temporal-service/temporal-service
Binary file not shown.
Loading