Files
autoAiWorkSys/_doc/任务与指令的区别说明.md
张成 e27c0dc41a 1
2025-11-26 15:00:14 +08:00

10 KiB
Raw Blame History

任务与指令的区别说明

📋 概述

在调度系统中,任务Task指令Command 是两个不同层次的概念,它们的关系是:一个任务可以包含多个指令

⚠️ 重要说明

当前系统实际情况

  • 真正的任务:目前只有 auto_deliver(自动投递任务)是真正的任务,它包含多个步骤和指令
  • 伪任务:虽然代码中有 get_resumeget_job_listsend_chatapply_job 等任务处理器,但它们实际上只是包装了单个指令,本质上就是直接执行指令

为什么会有伪任务

  1. 统一的任务追踪和日志记录
  2. 保持接口的一致性
  3. 未来可能扩展为真正的任务(包含多个步骤)

🔄 层级关系

任务Task
  ├── 指令1Command
  ├── 指令2Command
  └── 指令3Command

📊 详细对比

维度 任务Task 指令Command
概念层级 业务层 执行层
数据库表 task_status task_commands
管理模块 TaskQueue任务队列 CommandManager指令管理器
处理模块 TaskHandlers任务处理器 jobManager业务管理器
粒度 粗粒度(业务流程) 细粒度(具体操作)
包含关系 包含多个指令 属于某个任务
执行方式 由任务队列调度 由指令管理器执行
通信方式 内部调度 通过 MQTT 发送到客户端

🎯 任务Task

定义

任务是业务层面的概念,代表一个完整的业务流程或工作单元。

特点

  • 业务导向:代表一个完整的业务目标
  • 可包含多个步骤:一个任务可以包含多个指令
  • 有生命周期pending → running → completed/failed
  • 有优先级:可以设置任务优先级
  • 有超时机制:任务级别有超时保护

任务类型示例

真正的任务(包含多个步骤)

  • auto_deliver - 自动投递任务(包含多个子操作:获取简历、获取岗位列表、筛选职位、批量投递)
  • auto_chat - 自动沟通任务待实现自动与HR进行沟通回复消息等
  • auto_active_account - 自动活跃账号任务(待实现:自动执行操作保持账号活跃度)

注意:目前系统中只有 auto_deliver 是已实现的真正任务,auto_chatauto_active_account 是待实现的任务框架。

任务表结构task_status

{
  id: 1,
  sn_code: 'GHJU',
  taskType: 'auto_deliver',
  taskName: '自动投递 - 前端开发',
  status: 'running',
  priority: 7,
  taskParams: { keyword: '前端', platform: 'boss' },
  result: {},
  startTime: '2024-01-01 10:00:00',
  endTime: null,
  duration: 0
}

任务执行流程

// 1. 添加任务到队列
await taskQueue.addTask(sn_code, {
  taskType: 'auto_deliver',
  taskName: '自动投递',
  taskParams: { keyword: '前端' }
});

// 2. 任务队列调度执行
// 3. 任务处理器处理任务
// 4. 任务处理器创建并执行指令

⚙️ 指令Command

定义

指令是执行层面的概念,代表一个具体的操作,通过 MQTT 发送到客户端执行。

特点

  • 执行导向:代表一个具体的操作
  • 原子性:一个指令是一个不可分割的操作
  • 有执行顺序:指令可以按顺序执行
  • 有超时机制:指令级别有超时保护
  • MQTT 通信:通过 MQTT 发送到客户端

指令类型示例

  • getOnlineResume - 获取在线简历
  • getJobList - 获取岗位列表
  • applyJob - 投递简历
  • sendChatMessage - 发送聊天消息
  • getLoginQrCode - 获取登录二维码

指令表结构task_commands

{
  id: 1,
  task_id: 100,  // 关联的任务ID
  command_type: 'getOnlineResume',
  command_name: '获取在线简历',
  command_params: '{"sn_code":"GHJU"}',
  status: 'completed',
  sequence: 1,
  priority: 9,
  start_time: '2024-01-01 10:00:00',
  end_time: '2024-01-01 10:00:30',
  duration: 30000
}

指令执行流程

// 1. 任务处理器创建指令
const commands = [{
  command_type: 'getOnlineResume',
  command_name: '获取在线简历',
  command_params: JSON.stringify({ sn_code })
}];

// 2. 指令管理器执行指令
await command.executeCommands(taskId, commands, mqttClient);

// 3. 通过 MQTT 发送到客户端
// 4. 客户端执行并返回结果

🔗 关系示例

示例1自动投递任务

任务auto_deliver(自动投递任务)

包含的指令

  1. getOnlineResume - 获取在线简历
  2. getJobList - 获取岗位列表
  3. applyJob - 投递简历(可能多个)
// 任务处理器创建多个指令
async handleAutoDeliverTask(task) {
  // 1. 获取简历指令
  const getResumeCommand = {
    command_type: 'getOnlineResume',
    command_name: '获取在线简历',
    ...
  };
  
  // 2. 获取岗位列表指令
  const getJobListCommand = {
    command_type: 'getJobList',
    command_name: '获取岗位列表',
    ...
  };
  
  // 3. 投递指令(可能多个)
  const applyCommands = jobs.map(job => ({
    command_type: 'applyJob',
    command_name: `投递简历 - ${job.jobTitle}`,
    ...
  }));
  
  // 执行所有指令
  await command.executeCommands(task.id, [
    getResumeCommand,
    getJobListCommand,
    ...applyCommands
  ], mqttClient);
}

示例2获取简历伪任务实际是指令

说明:虽然代码中有 get_resume 任务处理器,但它实际上只是包装了单个指令,本质上就是直接执行指令。

任务get_resume(获取简历任务)

包含的指令

  1. getOnlineResume - 获取在线简历
async handleGetResumeTask(task) {
  // 实际上只是创建一个指令并执行
  const commands = [{
    command_type: 'getOnlineResume',
    command_name: '获取在线简历',
    command_params: JSON.stringify({ sn_code: task.sn_code })
  }];
  
  await command.executeCommands(task.id, commands, this.mqttClient);
}

注意:这种"任务"实际上可以直接作为指令执行,不需要通过任务队列。它们存在的原因可能是为了:

  1. 统一的任务追踪和日志记录
  2. 未来可能扩展为真正的任务(包含多个步骤)
  3. 保持接口的一致性

📈 执行流程图

┌─────────────────┐
│  任务队列        │
│  (TaskQueue)    │
└────────┬────────┘
         │ 调度任务
         ↓
┌─────────────────┐
│  任务处理器      │
│ (TaskHandlers)  │
└────────┬────────┘
         │ 创建指令
         ↓
┌─────────────────┐
│  指令管理器      │
│ (CommandManager)│
└────────┬────────┘
         │ 执行指令
         ↓
┌─────────────────┐
│  业务管理器      │
│  (jobManager)   │
└────────┬────────┘
         │ MQTT 发送
         ↓
┌─────────────────┐
│  客户端设备      │
│  (Python Client)│
└─────────────────┘

🎨 设计优势

1. 职责分离

  • 任务层:负责业务逻辑和流程编排
  • 指令层:负责具体操作和 MQTT 通信

2. 灵活性

  • 一个任务可以包含不同数量的指令
  • 可以根据业务需求动态创建指令

3. 可追踪性

  • 任务级别:可以追踪整个业务流程
  • 指令级别:可以追踪每个具体操作

4. 错误处理

  • 任务级别:处理业务逻辑错误
  • 指令级别:处理执行错误和超时

📝 代码示例

任务处理器创建指令

// api/middleware/schedule/taskHandlers.js
async handleAutoDeliverTask(task) {
  const { sn_code, taskParams } = task;
  
  // 1. 创建获取简历指令
  const getResumeCommand = {
    command_type: 'getOnlineResume',
    command_name: '获取在线简历',
    command_params: JSON.stringify({ sn_code, platform: 'boss' })
  };
  
  // 2. 创建获取岗位列表指令
  const getJobListCommand = {
    command_type: 'getJobList',
    command_name: '获取岗位列表',
    command_params: JSON.stringify({ 
      sn_code, 
      keyword: taskParams.keyword,
      platform: 'boss'
    })
  };
  
  // 3. 执行指令序列
  const result = await command.executeCommands(
    task.id, 
    [getResumeCommand, getJobListCommand], 
    this.mqttClient
  );
  
  return result;
}

指令管理器执行指令

// api/middleware/schedule/command.js
async executeCommand(taskId, command, mqttClient) {
  // 1. 创建指令记录
  const commandRecord = await db.getModel('task_commands').create({
    task_id: taskId,
    command_type: command.command_type,
    command_name: command.command_name,
    status: 'pending'
  });
  
  // 2. 调用业务管理器执行
  const result = await jobManager[commandType](
    sn_code, 
    mqttClient, 
    commandParams
  );
  
  // 3. 更新指令状态
  await this.updateCommandStatus(commandId, 'completed', result);
  
  return result;
}

🔍 总结

  • 任务Task:业务层面的工作单元,代表一个完整的业务流程

    • 真正的任务:包含多个步骤/指令,如 auto_deliver
    • 伪任务:虽然叫任务,但实际只是包装了单个指令,如 get_resumeget_job_list
  • 指令Command:执行层面的操作单元,代表一个具体的操作

    • 通过 MQTT 发送到客户端执行
    • 如:getOnlineResumegetJobListapplyJob
  • 关系

    • 真正的任务包含多个指令,指令按顺序执行
    • 伪任务只是指令的包装,本质上就是直接执行指令
  • 管理:任务由任务队列管理,指令由指令管理器管理

  • 通信:任务在服务端内部调度,指令通过 MQTT 发送到客户端

  • 当前状态

    • 目前系统中只有 auto_deliver 是真正的任务(包含多个步骤)
    • 其他如 get_resumeget_job_listsend_chatapply_job 虽然叫任务,但实际只是指令的包装

这种设计实现了业务逻辑和执行逻辑的分离,提高了系统的灵活性和可维护性。伪任务的存在可能是为了统一的任务追踪和未来扩展。