feat(watchdog): initialize watchdog connection and sync running instances

This commit is contained in:
2026-05-10 17:40:01 +08:00
parent ef27e7e0a9
commit e063a36e28
4 changed files with 54 additions and 18 deletions
+1
View File
@@ -72,6 +72,7 @@ func main() {
setupRoutes() setupRoutes()
// Initialize watchdog connection
err = watchdog.Init() err = watchdog.Init()
if err != nil { if err != nil {
postLog.Error(fmt.Sprintf("Unable to initialize Watchdog: %s", err)) postLog.Error(fmt.Sprintf("Unable to initialize Watchdog: %s", err))
+6 -6
View File
@@ -394,11 +394,11 @@ func IsInstanceRunning(instanceID int) error {
if strings.Contains(outputStr, "RUNNING") { if strings.Contains(outputStr, "RUNNING") {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is running", instance.Name)) postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is running", instance.Name))
return nil return nil
} else {
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is stopped", instance.Name))
return nil
} }
postLog.Info(fmt.Sprintf("[IsInstanceRunning] Windows service %s is stopped", instance.Name))
return fmt.Errorf("service %s is not running", serviceName)
case "systemd": case "systemd":
cmd := exec.Command("systemctl", "status", serviceName) cmd := exec.Command("systemctl", "status", serviceName)
@@ -465,13 +465,13 @@ func IsInstanceRunning(instanceID int) error {
if strings.Contains(outputStr, "is running") { if strings.Contains(outputStr, "is running") {
return nil return nil
} else {
return nil
} }
return fmt.Errorf("service %s is not running", serviceName)
default: default:
postLog.Error(fmt.Sprintf("[IsInstanceRunning] Unsupported init system: %s", initType)) postLog.Error(fmt.Sprintf("[IsInstanceRunning] Unsupported init system: %s", initType))
return nil return fmt.Errorf("unsupported init system: %s", initType)
} }
} }
+44 -8
View File
@@ -8,6 +8,7 @@ import (
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"strings" "strings"
"super-frpc/database"
"super-frpc/global" "super-frpc/global"
"super-frpc/postLog" "super-frpc/postLog"
"super-frpc/sys" "super-frpc/sys"
@@ -21,7 +22,6 @@ const socketPath = "/tmp/super-frpc-watchdog.sock"
var ( var (
localConn net.Conn localConn net.Conn
localConnMutex sync.Mutex localConnMutex sync.Mutex
isConnected bool
recvChan chan string recvChan chan string
stopRecvChan chan struct{} stopRecvChan chan struct{}
recvWg sync.WaitGroup recvWg sync.WaitGroup
@@ -47,15 +47,51 @@ func Init() error {
} }
localConnMutex.Lock() localConnMutex.Lock()
defer localConnMutex.Unlock()
recvChan = make(chan string, 100) recvChan = make(chan string, 100)
stopRecvChan = make(chan struct{}) stopRecvChan = make(chan struct{})
isConnected = false global.Is.WatchdogConnected = false
localConnMutex.Unlock()
if global.CurrentConfig.Watchdog.Enabled {
if !Connect() {
postLog.Warning("[watchdog] initial connect failed; caller may retry with Connect")
}
}
return nil return nil
} }
func syncRunningInstancesToWatchdog() {
instances, err := database.DBListFrpcInstances()
if err != nil {
postLog.Error(fmt.Sprintf("[watchdog] failed to list frpc instances: %v", err))
return
}
added := 0
for _, instance := range instances {
if err := sys.IsInstanceRunning(instance.ID); err != nil {
postLog.Debug(fmt.Sprintf("[watchdog] instance %d is not running: %v", instance.ID, err))
continue
}
serviceName, err := database.GetServiceNameByInstanceID(instance.ID)
if err != nil {
postLog.Warning(fmt.Sprintf("[watchdog] failed to get service name for instance %d: %v", instance.ID, err))
continue
}
if !AddInstance(serviceName) {
postLog.Warning(fmt.Sprintf("[watchdog] failed to add running instance %s to monitor list", serviceName))
continue
}
added++
}
postLog.Info(fmt.Sprintf("[watchdog] synced %d running instance(s) to monitor list", added))
}
func ensureWatchdogProcess() error { func ensureWatchdogProcess() error {
watchdogName, err := getWatchdogBinaryName() watchdogName, err := getWatchdogBinaryName()
if err != nil { if err != nil {
@@ -151,7 +187,7 @@ func localSocketConnect() error {
} }
localConn = conn localConn = conn
isConnected = true global.Is.WatchdogConnected = true
recvWg.Add(1) recvWg.Add(1)
go recvMsg() go recvMsg()
@@ -231,7 +267,7 @@ func recvMsg() {
if localConn != nil { if localConn != nil {
localConn.Close() localConn.Close()
localConn = nil localConn = nil
isConnected = false global.Is.WatchdogConnected = false
} }
localConnMutex.Unlock() localConnMutex.Unlock()
return return
@@ -262,7 +298,7 @@ func Destroy() error {
if localConn != nil { if localConn != nil {
err := localConn.Close() err := localConn.Close()
localConn = nil localConn = nil
isConnected = false global.Is.WatchdogConnected = false
if err != nil { if err != nil {
return fmt.Errorf("failed to close connection: %v", err) return fmt.Errorf("failed to close connection: %v", err)
} }
@@ -279,5 +315,5 @@ func Destroy() error {
func IsConnected() bool { func IsConnected() bool {
localConnMutex.Lock() localConnMutex.Lock()
defer localConnMutex.Unlock() defer localConnMutex.Unlock()
return isConnected && localConn != nil return global.Is.WatchdogConnected && localConn != nil
} }
+3 -4
View File
@@ -11,10 +11,6 @@ func Connect() bool {
return true return true
} }
if err := Init(); err != nil {
return false
}
deadline := time.Now().Add(5 * time.Second) deadline := time.Now().Add(5 * time.Second)
var lastErr error var lastErr error
for { for {
@@ -45,7 +41,10 @@ func Connect() bool {
return false return false
} }
syncRunningInstancesToWatchdog()
return true return true
} }
func Disconnect() bool { func Disconnect() bool {