refactor: 重构巡检报告调度器,移除设备依赖并优化重试逻辑
Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled

- 重构调度器,改为注入获取设备ID的回调,移除硬依赖的deviceStore
- 调整前端设备配置同步逻辑,改为直接读取解密后的本地存储
- 修改重试间隔,从15秒改为3秒,首次同步改为立即执行
- 调整日志级别,优化错误信息输出
This commit is contained in:
2026-10-15 14:15:16 +08:00
parent 2f9f8da48e
commit 2561001dca
6 changed files with 77 additions and 59 deletions

View File

@@ -1164,6 +1164,7 @@ function registerInspectionHandlers(ipcMain, options) {
readStorage: options.readStorage,
writeStorage: options.writeStorage,
runSnapshotFn: (deviceIds, trigger) => _runScheduledSnapshot(deviceIds, trigger),
getAllDeviceIdsFn: () => Object.keys(_hostConfigs || {}),
});
}
return saved;
@@ -1178,6 +1179,7 @@ function registerInspectionHandlers(ipcMain, options) {
readStorage: options.readStorage,
writeStorage: options.writeStorage,
runSnapshotFn: (deviceIds, trigger) => _runScheduledSnapshot(deviceIds, trigger),
getAllDeviceIdsFn: () => Object.keys(_hostConfigs || {}),
});
} else if (!cfg.enabled && reportScheduler.isRunning()) {
reportScheduler.stop();
@@ -1425,24 +1427,8 @@ function registerInspectionHandlers(ipcMain, options) {
console.log("[Inspection] IPC handlers 已注册");
return {
getScheduler: () => _scheduler,
createScheduler: (opts) => {
_scheduler = new InspectionScheduler({
readFn,
writeFn,
execFn: execCommand,
onAlertChanged: broadcastAlertChanged,
...opts,
});
return _scheduler;
},
};
// ─── Electron 启动时自动启动 reportScheduler ───
// 负责:per-device 定时快照 tick(主进程自身 SSH 执行) + dailyReport HH:MM 定时聚合
// 主进程从 _hostConfigs(InspectionScheduler 已初始化的已解密 SSH 凭据缓存)取配置
// 执行快照,不依赖 renderer 是否打开巡检报告页面
async function _runScheduledSnapshot(deviceIds, trigger = "scheduled") {
if (!_hostConfigs || Object.keys(_hostConfigs).length === 0) {
console.warn("[reportScheduler] _hostConfigs 未初始化,定时快照跳过(需先打开监控页面让 renderer 同步 SSH 凭据到主进程)");
@@ -1495,6 +1481,7 @@ function registerInspectionHandlers(ipcMain, options) {
readStorage: readFn,
writeStorage: writeFn,
runSnapshotFn: (deviceIds, trigger) => _runScheduledSnapshot(deviceIds, trigger),
getAllDeviceIdsFn: () => Object.keys(_hostConfigs || {}),
});
console.error("[RS_DEBUG] ✅ start() 已调用完成");
} else {
@@ -1503,6 +1490,20 @@ function registerInspectionHandlers(ipcMain, options) {
} catch (e) {
console.error("[RS_DEBUG] ❌ 启动失败:", e?.message || String(e), e?.stack);
}
return {
getScheduler: () => _scheduler,
createScheduler: (opts) => {
_scheduler = new InspectionScheduler({
readFn,
writeFn,
execFn: execCommand,
onAlertChanged: broadcastAlertChanged,
...opts,
});
return _scheduler;
},
};
}
module.exports = {

View File

@@ -30,11 +30,12 @@ let _deviceLastRun = new Map(); // deviceId → timestamp(用于 per-device
* @param {function} deps.runSnapshotFn - 定时快照执行函数(renderer 侧 Hook 实际负责执行,这里传空函数)
* @param {function} [deps.onDailyReportReady] - 日报告聚合完成后回调 async (report) => void
*/
function start({ readStorage, writeStorage, runSnapshotFn, onDailyReportReady }) {
function start({ readStorage, writeStorage, runSnapshotFn, onDailyReportReady, getAllDeviceIdsFn }) {
if (_tickTimer) return; // 已启动
const readFn = (k) => readStorage(k);
const writeFn = (k, v) => writeStorage(k, v);
const _getAllDeviceIds = getAllDeviceIdsFn;
const tick = async () => {
const cfg = reportScheduleStore.getSchedule(readFn);
@@ -47,14 +48,12 @@ function start({ readStorage, writeStorage, runSnapshotFn, onDailyReportReady })
// null/undefined = 全部;空数组 = 不巡检;非空数组 = 指定设备
let deviceIds = cfg.enabledDeviceIds;
if (deviceIds === null || deviceIds === undefined) {
// 全部设备 —— 从 deviceStore 拉所有设备 ID
try {
const deviceStore = require("./deviceStore.cjs");
const all = deviceStore.listDevices(readFn);
deviceIds = all.map(d => d.host_id || d.id).filter(Boolean);
console.log("[reportScheduler] tick: enabledDeviceIds=null, deviceStore.listDevices →", all.length, "台 → ids=", JSON.stringify(deviceIds));
} catch (e) {
console.error("[reportScheduler] ❌ 读取全部设备失败:", e?.message, e?.stack?.split("\n").slice(0,3).join("\n"));
// 全部设备 —— 通过回调拿(由调用方注入,避免依赖不存在的 deviceStore.listDevices)
if (typeof _getAllDeviceIds === "function") {
deviceIds = _getAllDeviceIds();
console.error("[reportScheduler] tick: enabledDeviceIds=null, _getAllDeviceIds →", deviceIds?.length || 0, "台");
} else {
console.error("[reportScheduler] ❌ 无 getAllDeviceIds 回调,跳过");
return;
}
} else if (Array.isArray(deviceIds) && deviceIds.length === 0) {