vdi-cloud/terminal/kiosk-shell/src/monitor.h
宋一鸣 162dcc1e02 初始化:导入 VDI 云终端代码与会话基础能力
变更详情:init: VDI 云终端代码(kiosk-shell 登录/桌面列表/Moonlight/RDP/看门狗)
2026-10-28 20:52:20 +08:00

66 lines
2.0 KiB
C++
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.

// 看门狗 Monitor(双进程架构)
//
// 对应《VDI 云桌面软件开发方案》与会议纪要:
// "必须部署独立的 Monitor(看门狗)程序监控主进程状态,
// 主进程假死或崩溃时由 Monitor 执行 kill 操作并重启"
// "小型 ARM 设备长时间运行必然出现卡顿或假死,无守护机制将导致用户体验严重受损"
//
// 判定主进程假死的方式:
// 1. 进程不存在 -> 崩溃
// 2. 心跳文件超时 -> 假死(主进程定期写心跳,Monitor 检查更新时间)
// 3. 连续启动失败 -> 熔断,放弃重启避免无限重启循环
//
// 用法:
// monitor -- <主进程命令行...>
// 例:monitor -- /home/armbian/vdi-terminal/bin/kiosk-shell
#ifndef KIOSK_SHELL_MONITOR_H
#define KIOSK_SHELL_MONITOR_H
#include <chrono>
#include <string>
namespace vdi {
struct MonitorConfig {
// 心跳文件路径;主进程每 heartbeatInterval 写一次
std::string heartbeatFile = "/tmp/vdi-kiosk.heartbeat";
// 心跳超时判定(毫秒)
int heartbeatTimeoutMs = 15000;
// 检查间隔(毫秒)
int checkIntervalMs = 3000;
// 心跳文件超过该时间认为进程从未启动
int startupGraceMs = 20000;
// 连续失败多少次后熔断
int maxRestartAttempts = 5;
// 两次重启之间的间隔(毫秒)
int restartBackoffMs = 3000;
// 是否在每条日志后写 stdout
bool verbose = true;
};
class Monitor {
public:
explicit Monitor(MonitorConfig config = MonitorConfig());
// 运行看门狗主循环,阻塞直到被信号中断
int run(const std::string& command);
// 请求退出(供信号处理调用)
void requestStop();
private:
bool isProcessAlive(pid_t pid) const;
// 主进程是否被认为假死
bool isHung() const;
void log(const std::string& message) const;
MonitorConfig config_;
volatile bool stopRequested_ = false;
int restartAttempts_ = 0;
};
} // namespace vdi
#endif // KIOSK_SHELL_MONITOR_H