fix(gateway): add stop subcommand to gracefully shutdown gateway (fixes #2373)
- Add 'picoclaw gateway stop' command to stop running gateway - Read PID file and send SIGTERM (Unix) or Kill (Windows) to process - Cross-platform implementation with build tags
This commit is contained in:
parent
31e05ea19c
commit
1e8754634b
3 changed files with 64 additions and 0 deletions
|
|
@ -2,12 +2,14 @@ package gateway
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/sipeed/picoclaw/cmd/picoclaw/internal"
|
||||
"github.com/sipeed/picoclaw/pkg/gateway"
|
||||
"github.com/sipeed/picoclaw/pkg/logger"
|
||||
"github.com/sipeed/picoclaw/pkg/pid"
|
||||
"github.com/sipeed/picoclaw/pkg/utils"
|
||||
)
|
||||
|
||||
|
|
@ -48,5 +50,42 @@ func NewGatewayCommand() *cobra.Command {
|
|||
"Continue starting even when no default model is configured",
|
||||
)
|
||||
|
||||
// Add stop subcommand
|
||||
cmd.AddCommand(newGatewayStopCommand())
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func newGatewayStopCommand() *cobra.Command {
|
||||
return &cobra.Command{
|
||||
Use: "stop",
|
||||
Short: "Stop the running picoclaw gateway",
|
||||
Long: "Stop the running picoclaw gateway by reading its PID file and sending a termination signal.",
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(_ *cobra.Command, _ []string) error {
|
||||
homePath := internal.GetPicoclawHome()
|
||||
|
||||
// Read PID file and check if process is running
|
||||
data := pid.ReadPidFileWithCheck(homePath)
|
||||
if data == nil {
|
||||
fmt.Println("gateway is not running")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find the process
|
||||
process, err := os.FindProcess(data.PID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to find gateway process (PID: %d): %w", data.PID, err)
|
||||
}
|
||||
|
||||
// Send termination signal
|
||||
fmt.Printf("stopping gateway (PID: %d)...\n", data.PID)
|
||||
if err := stopProcess(process); err != nil {
|
||||
return fmt.Errorf("failed to stop gateway (PID: %d): %w", data.PID, err)
|
||||
}
|
||||
|
||||
fmt.Println("gateway stopped successfully")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
13
cmd/picoclaw/internal/gateway/stop_unix.go
Normal file
13
cmd/picoclaw/internal/gateway/stop_unix.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//go:build !windows
|
||||
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
// stopProcess sends SIGTERM to the process for graceful shutdown on Unix-like systems.
|
||||
func stopProcess(process *os.Process) error {
|
||||
return process.Signal(syscall.SIGTERM)
|
||||
}
|
||||
12
cmd/picoclaw/internal/gateway/stop_windows.go
Normal file
12
cmd/picoclaw/internal/gateway/stop_windows.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
//go:build windows
|
||||
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"os"
|
||||
)
|
||||
|
||||
// stopProcess kills the process on Windows (SIGTERM is not supported).
|
||||
func stopProcess(process *os.Process) error {
|
||||
return process.Kill()
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue