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) }