1
This commit is contained in:
@@ -33,6 +33,16 @@ class ScheduledJobs {
|
||||
|
||||
this.jobs.push(monitoringJob);
|
||||
|
||||
// 启动离线设备任务清理定时任务(每分钟检查一次)
|
||||
const cleanupOfflineTasksJob = node_schedule.scheduleJob(config.schedules.monitoringInterval, async () => {
|
||||
await this.cleanupOfflineDeviceTasks().catch(error => {
|
||||
console.error('[定时任务] 清理离线设备任务失败:', error);
|
||||
});
|
||||
});
|
||||
|
||||
this.jobs.push(cleanupOfflineTasksJob);
|
||||
console.log('[定时任务] 已启动离线设备任务清理任务');
|
||||
|
||||
|
||||
// 执行自动投递任务
|
||||
const autoDeliverJob = node_schedule.scheduleJob(config.schedules.autoDeliver, () => {
|
||||
@@ -74,6 +84,96 @@ class ScheduledJobs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理离线设备任务
|
||||
* 检查离线超过10分钟的设备,取消其所有pending/running状态的任务
|
||||
*/
|
||||
async cleanupOfflineDeviceTasks() {
|
||||
try {
|
||||
const Sequelize = require('sequelize');
|
||||
const { device_status, task_status, op } = db.models;
|
||||
|
||||
// 离线阈值:10分钟
|
||||
const offlineThreshold = 10 * 60 * 1000; // 10分钟
|
||||
const now = new Date();
|
||||
const thresholdTime = new Date(now.getTime() - offlineThreshold);
|
||||
|
||||
// 查询离线超过10分钟的设备
|
||||
const offlineDevices = await device_status.findAll({
|
||||
where: {
|
||||
isOnline: false,
|
||||
lastHeartbeatTime: {
|
||||
[op.lt]: thresholdTime
|
||||
}
|
||||
},
|
||||
attributes: ['sn_code', 'lastHeartbeatTime']
|
||||
});
|
||||
|
||||
if (!offlineDevices || offlineDevices.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const offlineSnCodes = offlineDevices.map(dev => dev.sn_code);
|
||||
console.log(`[清理离线任务] 发现 ${offlineSnCodes.length} 个离线超过10分钟的设备: ${offlineSnCodes.join(', ')}`);
|
||||
|
||||
let totalCancelled = 0;
|
||||
|
||||
// 为每个离线设备取消任务
|
||||
for (const sn_code of offlineSnCodes) {
|
||||
try {
|
||||
// 查询该设备的所有pending/running任务
|
||||
const pendingTasks = await task_status.findAll({
|
||||
where: {
|
||||
sn_code: sn_code,
|
||||
status: ['pending', 'running']
|
||||
},
|
||||
attributes: ['id']
|
||||
});
|
||||
|
||||
if (pendingTasks.length === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 更新任务状态为cancelled
|
||||
const updateResult = await task_status.update(
|
||||
{
|
||||
status: 'cancelled',
|
||||
endTime: new Date(),
|
||||
result: JSON.stringify({
|
||||
reason: '设备离线超过10分钟,任务已自动取消',
|
||||
offlineTime: offlineDevices.find(d => d.sn_code === sn_code)?.lastHeartbeatTime
|
||||
})
|
||||
},
|
||||
{
|
||||
where: {
|
||||
sn_code: sn_code,
|
||||
status: ['pending', 'running']
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const cancelledCount = Array.isArray(updateResult) ? updateResult[0] : updateResult;
|
||||
totalCancelled += cancelledCount;
|
||||
|
||||
// 从内存队列中移除任务
|
||||
if (this.taskQueue && typeof this.taskQueue.cancelDeviceTasks === 'function') {
|
||||
await this.taskQueue.cancelDeviceTasks(sn_code);
|
||||
}
|
||||
|
||||
console.log(`[清理离线任务] 设备 ${sn_code} 已取消 ${cancelledCount} 个任务`);
|
||||
} catch (error) {
|
||||
console.error(`[清理离线任务] 取消设备 ${sn_code} 的任务失败:`, error);
|
||||
}
|
||||
}
|
||||
|
||||
if (totalCancelled > 0) {
|
||||
console.log(`[清理离线任务] 共取消 ${totalCancelled} 个离线设备的任务`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('[清理离线任务] 执行失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动投递任务
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user