fix(watchdog): now the client could successfully send more msgs to watchdog instead of the only connection msg
- Add debug logging for watchdog operations - Standardize message format for instance operations - Improve TCP message handling with proper line termination - Enhance error handling in watchdog operations - Add proper cleanup of recvChan in sendMsg - Update response handling in instance handlers
This commit is contained in:
@@ -627,7 +627,11 @@ func StartInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if is.watchdogConnected {
|
if is.watchdogConnected {
|
||||||
watchdog.AddInstance(serviceName)
|
if !watchdog.AddInstance(serviceName) {
|
||||||
|
postLog.Warning(fmt.Sprintf("[StartInstanceHandler] Failed to add watchdog instance %s", serviceName))
|
||||||
|
SendSuccessResponse(w, "Instance started successfully but watchdog instance add failed", nil)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SendSuccessResponse(w, "Instance started successfully", nil)
|
SendSuccessResponse(w, "Instance started successfully", nil)
|
||||||
@@ -702,7 +706,7 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Windows service %s stopped successfully", serviceName))
|
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Windows service %s stopped successfully", serviceName))
|
||||||
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
// SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||||
|
|
||||||
case "systemd":
|
case "systemd":
|
||||||
if err := StopSystemdService(serviceName); err != nil {
|
if err := StopSystemdService(serviceName); err != nil {
|
||||||
@@ -711,7 +715,7 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Systemd service %s stopped successfully", serviceName))
|
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Systemd service %s stopped successfully", serviceName))
|
||||||
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
// SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||||
|
|
||||||
case "init.d":
|
case "init.d":
|
||||||
if err := StopInitDService(serviceName); err != nil {
|
if err := StopInitDService(serviceName); err != nil {
|
||||||
@@ -720,13 +724,22 @@ func StopInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Init.d service %s stopped successfully", serviceName))
|
postLog.Info(fmt.Sprintf("[StopInstanceHandler] Init.d service %s stopped successfully", serviceName))
|
||||||
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
// SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Unsupported init system: %s", initType))
|
postLog.Error(fmt.Sprintf("[StopInstanceHandler] Unsupported init system: %s", initType))
|
||||||
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
|
SendErrorResponse(w, http.StatusInternalServerError, fmt.Sprintf("Unsupported init system: %s", initType))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if is.watchdogConnected {
|
||||||
|
if !watchdog.RemoveInstance(serviceName) {
|
||||||
|
postLog.Warning(fmt.Sprintf("[StopInstanceHandler] Failed to remove watchdog instance %s", serviceName))
|
||||||
|
SendSuccessResponse(w, "Instance stopped successfully but watchdog instance remove failed", nil)
|
||||||
|
} else {
|
||||||
|
SendSuccessResponse(w, "Instance stopped successfully", nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
func RestartInstanceHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|||||||
+30
-4
@@ -2,23 +2,45 @@ package watchdog
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"super-frpc/postLog"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AddInstance(serviceName string) bool {
|
func AddInstance(serviceName string) bool {
|
||||||
|
postLog.Debug(fmt.Sprintf("[watchdog] Add service monitor: %s", serviceName))
|
||||||
if !IsConnected() {
|
if !IsConnected() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
message := fmt.Sprintf("[instance.add] <serviceName>%s</serviceName>", serviceName)
|
message := fmt.Sprintf("[monitor.add] <serviceName>%s</serviceName>", serviceName)
|
||||||
response, err := sendMsg(message, 3)
|
response, err := sendMsg(message, 3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
} else if response == "success" {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return response == "success"
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveInstance(serviceName string) bool {
|
func RemoveInstance(serviceName string) bool {
|
||||||
|
postLog.Debug(fmt.Sprintf("[watchdog] Remove service monitor: %s", serviceName))
|
||||||
|
if !IsConnected() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
message := fmt.Sprintf("[monitor.remove] <serviceName>%s</serviceName>", serviceName)
|
||||||
|
response, err := sendMsg(message, 3)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
} else if response == "success" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func CloseInstance(serviceName string) bool {
|
||||||
|
postLog.Debug(fmt.Sprintf("[watchdog] Remove service monitor: %s", serviceName))
|
||||||
if !IsConnected() {
|
if !IsConnected() {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -27,9 +49,11 @@ func RemoveInstance(serviceName string) bool {
|
|||||||
response, err := sendMsg(message, 3)
|
response, err := sendMsg(message, 3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
} else if response == "success" {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return response == "success"
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func Close() bool {
|
func Close() bool {
|
||||||
@@ -41,7 +65,9 @@ func Close() bool {
|
|||||||
response, err := sendMsg(message, 3)
|
response, err := sendMsg(message, 3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
} else if response == "success" {
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return response == "success"
|
return false
|
||||||
}
|
}
|
||||||
+51
-51
@@ -4,10 +4,10 @@ import (
|
|||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"super-frpc/postLog"
|
"super-frpc/postLog"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -57,7 +57,7 @@ func tcpConnect(ipaddr string, port int) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendMsg(message string, target int) (string, error) {
|
func sendMsg(message string, timeout int) (string, error) {
|
||||||
tcpConnMutex.Lock()
|
tcpConnMutex.Lock()
|
||||||
|
|
||||||
if tcpConn == nil {
|
if tcpConn == nil {
|
||||||
@@ -65,7 +65,7 @@ func sendMsg(message string, target int) (string, error) {
|
|||||||
return "", fmt.Errorf("not connected")
|
return "", fmt.Errorf("not connected")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := tcpConn.Write([]byte(message))
|
_, err := tcpConn.Write([]byte(message + "\n"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
tcpConnMutex.Unlock()
|
tcpConnMutex.Unlock()
|
||||||
return "", fmt.Errorf("failed to send message: %v", err)
|
return "", fmt.Errorf("failed to send message: %v", err)
|
||||||
@@ -75,68 +75,68 @@ func sendMsg(message string, target int) (string, error) {
|
|||||||
|
|
||||||
select {
|
select {
|
||||||
case response := <-recvChan:
|
case response := <-recvChan:
|
||||||
return response, nil
|
for len(recvChan) > 0 {
|
||||||
case <-time.After(time.Duration(target) * time.Second):
|
<-recvChan
|
||||||
|
}
|
||||||
|
return strings.TrimSpace(response), nil
|
||||||
|
case <-time.After(time.Duration(timeout) * time.Second):
|
||||||
return "", fmt.Errorf("timeout waiting for response")
|
return "", fmt.Errorf("timeout waiting for response")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func recvMsg() {
|
func recvMsg() {
|
||||||
defer recvWg.Done()
|
defer recvWg.Done()
|
||||||
|
|
||||||
tcpConnMutex.Lock()
|
tcpConnMutex.Lock()
|
||||||
if tcpConn == nil {
|
if tcpConn == nil {
|
||||||
tcpConnMutex.Unlock()
|
tcpConnMutex.Unlock()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn := tcpConn
|
conn := tcpConn
|
||||||
tcpConnMutex.Unlock()
|
tcpConnMutex.Unlock()
|
||||||
|
|
||||||
reader := bufio.NewReader(conn)
|
reader := bufio.NewReader(conn)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-stopRecvChan:
|
case <-stopRecvChan:
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
conn.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
|
||||||
|
|
||||||
// ⭐ 改为读取到换行符 \n 为止
|
data, err := reader.ReadBytes('\n')
|
||||||
data, err := reader.ReadBytes('\n')
|
|
||||||
|
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
// ⭐ 用 strings.TrimSpace 去掉末尾的 \n
|
line := strings.TrimSpace(string(data))
|
||||||
line := strings.TrimSpace(string(data))
|
|
||||||
|
|
||||||
if len(line) > 0 {
|
if len(line) > 0 {
|
||||||
select {
|
select {
|
||||||
case recvChan <- line:
|
case recvChan <- line:
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isResponseMessage(line) {
|
if !isResponseMessage(line) {
|
||||||
postLog.Debug(fmt.Sprintf("[Watchdog] TCP Socket received message: %s", line))
|
postLog.Debug(fmt.Sprintf("[Watchdog] TCP Socket received message: %s", line))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// 处理非超时的严重错误(如服务端断开)
|
tcpConnMutex.Lock()
|
||||||
tcpConnMutex.Lock()
|
if tcpConn != nil {
|
||||||
if tcpConn != nil {
|
tcpConn.Close()
|
||||||
tcpConn.Close()
|
tcpConn = nil
|
||||||
tcpConn = nil
|
isConnected = false
|
||||||
isConnected = false
|
}
|
||||||
}
|
tcpConnMutex.Unlock()
|
||||||
tcpConnMutex.Unlock()
|
return
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func isResponseMessage(msg string) bool {
|
func isResponseMessage(msg string) bool {
|
||||||
|
|||||||
Reference in New Issue
Block a user