1
This commit is contained in:
@@ -6,6 +6,8 @@ const command = require('./command');
|
||||
const PriorityQueue = require('./PriorityQueue');
|
||||
const ErrorHandler = require('./ErrorHandler');
|
||||
const deviceManager = require('./deviceManager');
|
||||
const ScheduleUtils = require('./utils');
|
||||
const ScheduleConfig = require('./config');
|
||||
|
||||
/**
|
||||
* 任务队列管理器(重构版)
|
||||
@@ -548,7 +550,7 @@ class TaskQueue {
|
||||
}
|
||||
|
||||
/**
|
||||
* 执行任务(统一重试机制)
|
||||
* 执行任务(统一重试机制 + 超时保护)
|
||||
* @param {object} task - 任务对象
|
||||
*/
|
||||
async executeTask(task) {
|
||||
@@ -587,8 +589,16 @@ class TaskQueue {
|
||||
throw new Error(`未找到任务类型 ${task.taskType} 的处理器,请先注册处理器`);
|
||||
}
|
||||
|
||||
// 执行任务处理器
|
||||
const result = await handler(task);
|
||||
// 获取任务超时时间(从配置中获取,默认10分钟)
|
||||
const taskTimeout = ScheduleConfig.getTaskTimeout(task.taskType) || 10 * 60 * 1000;
|
||||
|
||||
// 使用超时机制包装任务执行,防止任务卡住
|
||||
const taskPromise = handler(task);
|
||||
const result = await ScheduleUtils.withTimeout(
|
||||
taskPromise,
|
||||
taskTimeout,
|
||||
`任务执行超时: ${task.taskName} (任务类型: ${task.taskType}, 超时时间: ${taskTimeout / 1000}秒)`
|
||||
);
|
||||
|
||||
// 任务成功
|
||||
task.status = 'completed';
|
||||
@@ -613,46 +623,64 @@ class TaskQueue {
|
||||
} catch (error) {
|
||||
// 使用统一错误处理
|
||||
const errorInfo = await ErrorHandler.handleError(error, {
|
||||
taskId: task.id,
|
||||
task_id: task.id,
|
||||
sn_code: task.sn_code,
|
||||
taskType: task.taskType,
|
||||
taskName: task.taskName
|
||||
});
|
||||
|
||||
|
||||
// 直接标记为失败(重试已禁用)
|
||||
task.status = 'failed';
|
||||
task.endTime = new Date();
|
||||
task.duration = Date.now() - startTime;
|
||||
task.errorMessage = errorInfo.message || error.message || '未知错误';
|
||||
task.errorStack = errorInfo.stack || error.stack || '';
|
||||
// 直接标记为失败(重试已禁用)
|
||||
task.status = 'failed';
|
||||
task.endTime = new Date();
|
||||
task.duration = Date.now() - startTime;
|
||||
task.errorMessage = errorInfo.message || error.message || '未知错误';
|
||||
task.errorStack = errorInfo.stack || error.stack || '';
|
||||
|
||||
console.error(`[任务队列] 任务执行失败: ${task.taskName} (ID: ${task.id}), 错误: ${task.errorMessage}`, {
|
||||
errorStack: task.errorStack,
|
||||
taskId: task.id,
|
||||
sn_code: task.sn_code,
|
||||
taskType: task.taskType
|
||||
});
|
||||
|
||||
// 更新数据库任务状态为失败
|
||||
try {
|
||||
await db.getModel('task_status').update(
|
||||
{
|
||||
status: 'failed',
|
||||
endTime: task.endTime,
|
||||
duration: task.duration,
|
||||
result: JSON.stringify({
|
||||
error: task.errorMessage,
|
||||
stack: task.errorStack
|
||||
}),
|
||||
progress: 0
|
||||
},
|
||||
{ where: { id: task.id } }
|
||||
);
|
||||
} catch (dbError) {
|
||||
console.error(`[任务队列] 更新任务失败状态到数据库失败:`, dbError);
|
||||
}
|
||||
|
||||
console.error(`[任务队列] 任务执行失败: ${task.taskName} (ID: ${task.id}), 错误: ${task.errorMessage}`, {
|
||||
errorStack: task.errorStack,
|
||||
task_id: task.id,
|
||||
sn_code: task.sn_code,
|
||||
taskType: task.taskType,
|
||||
duration: task.duration
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消任务
|
||||
* @param {string} taskId - 任务ID
|
||||
* @param {string} task_id - 任务ID
|
||||
* @returns {Promise<boolean>} 是否成功取消
|
||||
*/
|
||||
async cancelTask(taskId) {
|
||||
async cancelTask(task_id) {
|
||||
// 遍历所有设备队列查找任务
|
||||
for (const [sn_code, queue] of this.deviceQueues.entries()) {
|
||||
const removed = queue.remove(task => task.id === taskId);
|
||||
const removed = queue.remove(task => task.id === task_id);
|
||||
|
||||
if (removed) {
|
||||
// 检查是否正在执行
|
||||
const status = this.deviceStatus.get(sn_code);
|
||||
if (status && status.currentTask && status.currentTask.id === taskId) {
|
||||
if (status && status.currentTask && status.currentTask.id === task_id) {
|
||||
// 正在执行的任务无法取消,只能标记
|
||||
console.warn(`[任务队列] 任务 ${taskId} 正在执行,无法取消`);
|
||||
console.warn(`[任务队列] 任务 ${task_id} 正在执行,无法取消`);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -662,10 +690,10 @@ class TaskQueue {
|
||||
status: 'cancelled',
|
||||
endTime: new Date()
|
||||
},
|
||||
{ where: { id: taskId } }
|
||||
{ where: { id: task_id } }
|
||||
);
|
||||
|
||||
console.log(`[任务队列] 任务已取消: ${taskId}`);
|
||||
console.log(`[任务队列] 任务已取消: ${task_id}`);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -766,13 +794,13 @@ class TaskQueue {
|
||||
|
||||
/**
|
||||
* 获取任务状态
|
||||
* @param {string} taskId - 任务ID
|
||||
* @param {string} task_id - 任务ID
|
||||
* @returns {Promise<object|null>} 任务对象
|
||||
*/
|
||||
async getTaskStatus(taskId) {
|
||||
async getTaskStatus(task_id) {
|
||||
// 先从内存中查找
|
||||
for (const queue of this.deviceQueues.values()) {
|
||||
const task = queue.find(t => t.id === taskId);
|
||||
const task = queue.find(t => t.id === task_id);
|
||||
if (task) {
|
||||
return task;
|
||||
}
|
||||
@@ -780,7 +808,7 @@ class TaskQueue {
|
||||
|
||||
// 从正在执行的任务中查找
|
||||
for (const status of this.deviceStatus.values()) {
|
||||
if (status.currentTask && status.currentTask.id === taskId) {
|
||||
if (status.currentTask && status.currentTask.id === task_id) {
|
||||
return status.currentTask;
|
||||
}
|
||||
}
|
||||
@@ -788,7 +816,7 @@ class TaskQueue {
|
||||
// 从数据库中查找
|
||||
try {
|
||||
const taskRecord = await db.getModel('task_status').findOne({
|
||||
where: { id: taskId }
|
||||
where: { id: task_id }
|
||||
});
|
||||
|
||||
if (taskRecord) {
|
||||
@@ -796,7 +824,7 @@ class TaskQueue {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[任务队列] 查询任务状态失败:`, error, {
|
||||
taskId: taskId
|
||||
task_id: task_id
|
||||
});
|
||||
}
|
||||
|
||||
@@ -858,24 +886,24 @@ class TaskQueue {
|
||||
});
|
||||
console.log(`[任务队列] 已删除任务指令记录: ${commandsDeleted} 条`);
|
||||
|
||||
// 删除聊天记录中关联的任务记录(删除所有有 taskId 且不为空的记录)
|
||||
// 删除聊天记录中关联的任务记录(删除所有有 task_id 且不为空的记录)
|
||||
const chatRecordsDeleted = await chatRecordsModel.destroy({
|
||||
where: {
|
||||
[Sequelize.Op.and]: [
|
||||
{ taskId: { [Sequelize.Op.ne]: null } },
|
||||
{ taskId: { [Sequelize.Op.ne]: '' } }
|
||||
{ task_id: { [Sequelize.Op.ne]: null } },
|
||||
{ task_id: { [Sequelize.Op.ne]: '' } }
|
||||
]
|
||||
},
|
||||
truncate: false
|
||||
});
|
||||
console.log(`[任务队列] 已删除聊天记录: ${chatRecordsDeleted} 条`);
|
||||
|
||||
// 删除投递记录中关联的任务记录(删除所有有 taskId 且不为空的记录)
|
||||
// 删除投递记录中关联的任务记录(删除所有有 task_id 且不为空的记录)
|
||||
const applyRecordsDeleted = await applyRecordsModel.destroy({
|
||||
where: {
|
||||
[Sequelize.Op.and]: [
|
||||
{ taskId: { [Sequelize.Op.ne]: null } },
|
||||
{ taskId: { [Sequelize.Op.ne]: '' } }
|
||||
{ task_id: { [Sequelize.Op.ne]: null } },
|
||||
{ task_id: { [Sequelize.Op.ne]: '' } }
|
||||
]
|
||||
},
|
||||
truncate: false
|
||||
|
||||
Reference in New Issue
Block a user