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

355 lines
10 KiB
Markdown
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.
# 任务与指令的区别说明
## 📋 概述
在调度系统中,**任务Task** 和 **指令Command** 是两个不同层次的概念,它们的关系是:**一个任务可以包含多个指令**。
### ⚠️ 重要说明
**当前系统实际情况**
- **真正的任务**:目前只有 `auto_deliver`(自动投递任务)是真正的任务,它包含多个步骤和指令
- **伪任务**:虽然代码中有 `get_resume``get_job_list``send_chat``apply_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_chat``auto_active_account` 是待实现的任务框架。
### 任务表结构task_status
```javascript
{
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
}
```
### 任务执行流程
```javascript
// 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
```javascript
{
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
}
```
### 指令执行流程
```javascript
// 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` - 投递简历(可能多个)
```javascript
// 任务处理器创建多个指令
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` - 获取在线简历
```javascript
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. **错误处理**
- 任务级别:处理业务逻辑错误
- 指令级别:处理执行错误和超时
## 📝 代码示例
### 任务处理器创建指令
```javascript
// 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;
}
```
### 指令管理器执行指令
```javascript
// 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_resume``get_job_list`
- **指令Command**:执行层面的操作单元,代表一个具体的操作
- 通过 MQTT 发送到客户端执行
- 如:`getOnlineResume``getJobList``applyJob`
- **关系**
- 真正的任务包含多个指令,指令按顺序执行
- 伪任务只是指令的包装,本质上就是直接执行指令
- **管理**:任务由任务队列管理,指令由指令管理器管理
- **通信**:任务在服务端内部调度,指令通过 MQTT 发送到客户端
- **当前状态**
- 目前系统中只有 `auto_deliver` 是真正的任务(包含多个步骤)
- 其他如 `get_resume``get_job_list``send_chat``apply_job` 虽然叫任务,但实际只是指令的包装
这种设计实现了业务逻辑和执行逻辑的分离,提高了系统的灵活性和可维护性。伪任务的存在可能是为了统一的任务追踪和未来扩展。