FireLeave_tool/connect/heartbeat.go
2025-12-10 14:34:57 +08:00

89 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package connect
import (
"fmt"
"os"
"os/exec"
"sync"
"time"
"FireLeave_tool/logger"
)
var (
InferenceProcesses sync.Map // key: deviceUUID string, value: *exec.Cmd
// 记录最后一次收到心跳的时间
inferenceLastHeartbeat sync.Map // key: deviceUUID string, value: time.Time
)
// UpdateInferenceHeartbeat 每收到一帧 /video/post 就调用这个
func UpdateInferenceHeartbeat(deviceUUID string) {
inferenceLastHeartbeat.Store(deviceUUID, time.Now())
}
// ShouldRestartInference 判断是否需要重启推理程序
func ShouldRestartInference(deviceUUID string) bool {
val, ok := inferenceLastHeartbeat.Load(deviceUUID)
if !ok {
return true // 从未收到过心跳,肯定要启动
}
last := val.(time.Time)
return time.Since(last) > 85*time.Second
}
// StopInferenceProcess 停止推理进程(供 main 和 DeviceManager 调用)
func StopInferenceProcess(deviceUUID string) {
if raw, ok := InferenceProcesses.Load(deviceUUID); ok {
if cmd, ok := raw.(*exec.Cmd); ok && cmd.Process != nil {
logger.Logger.Printf("正在停止推理进程 (DeviceUUID=%s, PID=%d)", deviceUUID, cmd.Process.Pid)
cmd.Process.Kill()
cmd.Wait()
}
InferenceProcesses.Delete(deviceUUID)
}
}
// StartInferenceProcess 重启推理程序(保持原端口!)
func StartInferenceProcess(deviceData *DeviceData) {
StopInferenceProcess(deviceData.DeviceUUID)
port, err := GlobalPortManager.GetPort(deviceData.DeviceUUID)
if err != nil {
logger.Logger.Printf("获取端口失败,无法重启推理程序 (DeviceUUID=%s): %v", deviceData.DeviceUUID, err)
return
}
detectAreaStr := ProcessDetectAreaForInference(deviceData.DetectArea)
inferenceCmd := exec.Command(
"./yolov5",
"-s", deviceData.CameraRTSP,
"-m", "model",
"-c", deviceData.DeviceUUID,
"-p", fmt.Sprintf("%d", port),
"-w", detectAreaStr,
"-r", fmt.Sprintf("%d", deviceData.Confidence),
)
inferenceCmd.Stdout = os.Stdout
inferenceCmd.Stderr = os.Stderr
logger.Logger.Printf("正在重启推理程序 (使用原端口 %d): %v", port, inferenceCmd.Args)
if err := inferenceCmd.Start(); err != nil {
logger.Logger.Printf("推理程序重启失败 (DeviceUUID=%s): %v", deviceData.DeviceUUID, err)
return
}
// 保存进程对象
InferenceProcesses.Store(deviceData.DeviceUUID, inferenceCmd)
logger.Logger.Printf("推理程序已成功重启PID=%d (DeviceUUID=%s, Port=%d)",
inferenceCmd.Process.Pid, deviceData.DeviceUUID, port)
// 重启后立即刷新一次心跳,防止 30s 检测又触发
UpdateInferenceHeartbeat(deviceData.DeviceUUID)
}