chore: init bj_power monorepo (dashboard/mes/wms/wms_client/workstation), clear subproject git metadata and align naming to folder names
This commit is contained in:
@@ -0,0 +1,233 @@
|
||||
# EventLoop: 理想模型推进计划
|
||||
|
||||
> 目标:EventLoop 为唯一状态读/写路径,JobRuntime 退化为复杂动作执行器。
|
||||
> 进行中状态 -> 直接转 DB 调度。
|
||||
|
||||
## 当前架构 v1(2026-05-10)
|
||||
|
||||
```
|
||||
简单路径 (Scan/Mark/Load/Unload):
|
||||
EventLoop → Worker dispatch → WorkerResult
|
||||
→ SetJobContext/Position + NotifyStepComplete
|
||||
→ JobRuntime.HandleTaskComplete → 步骤推进 → enqueueCurrentStep → notifyReady
|
||||
→ SendScheduleTick → EventLoop → trySchedule
|
||||
|
||||
复杂路径 (Exchange/Cleaning/Washer):
|
||||
EventLoop → SubmitCandidates → JobRuntime.buildXxxAction → ActionFn 闭包
|
||||
→ Dispatcher.Enqueue → robotWorker → task.Execute → jr.HandleTaskComplete
|
||||
|
||||
DB 角色:
|
||||
- job 表:status, position_type, position_ref_id, current_step_index, temp_slot_no
|
||||
- equipment_slot 表:status, current_job_id
|
||||
- task 表:仅 Dispatcher 路径使用
|
||||
```
|
||||
|
||||
### v1 的问题
|
||||
|
||||
1. **双推进路径**:`HandleTaskComplete`(JobRuntime)和 `advanceJobStep`(EventLoop)同时存在
|
||||
2. **JobRuntime 状态缓存与 DB 不一致风险**:内存 `Context`/`PositionType`/`State` 可能滞后于 DB
|
||||
3. **`jr.Start()` 是多余的入口**:调度应直接从 DB 读状态决定候选,不应依赖 JobRuntime 的 `enqueueCurrentStep`
|
||||
4. **`enqueueCurrentStep → notifyReady` 仍通过 JobRuntime**:简单路径的步骤推进仍需要 JobRuntime
|
||||
|
||||
## 理想架构 v3
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ EventLoop (唯一路径) │
|
||||
│ │
|
||||
MachineDone ──→│ handleMachineDone │
|
||||
│ ├─ DB: slot OCCUPIED→DONE │
|
||||
│ ├─ wake jobs │
|
||||
│ └─ trySchedule │
|
||||
│ │
|
||||
Inspection ───→│ handleInspectionResult │
|
||||
│ ├─ DB: set context │
|
||||
│ ├─ advanceStep (DB only) │
|
||||
│ └─ trySchedule │
|
||||
│ │
|
||||
WorkerResult ─→│ handleWorkerResult │
|
||||
│ ├─ DB: set context/position │
|
||||
│ ├─ advanceStep (DB only) │
|
||||
│ └─ trySchedule │
|
||||
│ │
|
||||
Command ──────→│ handleXxx │
|
||||
│ └─ trySchedule │
|
||||
│ │
|
||||
trySchedule ──→│ 刷新 DB 快照 │
|
||||
│ ├─ 构建 JobView + SystemState │
|
||||
│ ├─ 运行三层调度器 │
|
||||
│ ├─ MachineWait → 标记 DB │
|
||||
│ ├─ Decision → 更新 Context + 推进 │
|
||||
│ ├─ BufferStage → 更新位置 + 推进 │
|
||||
│ ├─ Scan/Mark → go dispatchWorker │
|
||||
│ ├─ Load/Unload → go dispatchWorker │
|
||||
│ └─ Exchange等 → SubmitCandidates │
|
||||
│ └─ Dispatcher (仅复杂动作) │
|
||||
│ │
|
||||
Worker 结果 ──→│ handleWorkerResult │
|
||||
│ └─ advanceStep (DB only) → trySchedule │
|
||||
└─────────────────────────────────────┘
|
||||
|
||||
JobRuntime (仅用于复杂动作):
|
||||
Exchange/Cleaning/Washer 的 ActionFn 闭包
|
||||
不再承担: enqueueCurrentStep, notifyReady, syncStatusToDB
|
||||
DB 状态完全由 EventLoop 读写
|
||||
```
|
||||
|
||||
## 推进计划(4 个 Phase)
|
||||
|
||||
### Phase 1: 简单路径完全脱离 JobRuntime
|
||||
|
||||
**目标**:Scan/Mark/Load/Unload 路径不经过 `HandleTaskComplete`,
|
||||
而是由 EventLoop 的 `handleWorkerResult` 直接推进 DB 步骤。
|
||||
|
||||
**现状**:
|
||||
```
|
||||
WorkerResult → SetJobContext/Position + NotifyStepComplete
|
||||
→ jr.HandleTaskComplete → buildBranchConditions
|
||||
→ GetNextStepIndex → jr.CurrentStepIdx = nextIdx
|
||||
→ syncStatusToDB → enqueueCurrentStep → notifyReady → SendScheduleTick
|
||||
```
|
||||
|
||||
**目标**:
|
||||
```
|
||||
WorkerResult → EventLoop.advanceStep(jobID, ctxUpdates)
|
||||
→ DB: 读 Context → 分支条件 → 写 CurrentStepIndex + Context
|
||||
→ SendScheduleTick → trySchedule
|
||||
```
|
||||
|
||||
**改动点**:
|
||||
1. `DBState` 新增 `AdvanceStep(ctx, jobID, contextUpdates)` 方法
|
||||
- 读 job.context + 当前 recipe step
|
||||
- 计算分支条件 → 下一步索引
|
||||
- 如果是最后一步 → FinishJob
|
||||
- 否则 → CompleteStep + 写 context
|
||||
2. `handleWorkerResult` EventLoop 直派路径改为调用 `db.AdvanceStep`
|
||||
3. 删除 `NotifyStepComplete` 调用(不再需要 JobRuntime)
|
||||
4. `SetJobContext` / `SetJobPosition` 改为 DB 直写
|
||||
|
||||
**风险**:低——不影响复杂路径,简单路径已有 Worker 直派基础。
|
||||
|
||||
### Phase 2: 调度入口去 JobRuntime 化
|
||||
|
||||
**目标**:`trySchedule` 独立于 JobRuntime 运行,不依赖 `SubmitCandidates` 的
|
||||
MachineWait/Decision/BufferStage 处理。
|
||||
|
||||
**现状**:
|
||||
```
|
||||
trySchedule → 构建 views → 跑调度器 → Workers + SubmitCandidates
|
||||
SubmitCandidates → jr.State = WAITING_MACHINE (MachineWait)
|
||||
→ jr.HandleTaskComplete(...) (Decision/BufferStage)
|
||||
```
|
||||
|
||||
**目标**:
|
||||
```
|
||||
trySchedule → 构建 views → 跑调度器
|
||||
→ MachineWait: DB 写 job.status = WAITING_UNLOAD
|
||||
→ Decision: DB 读 context + 写 context + advanceStep
|
||||
→ BufferStage: DB 写 position + advanceStep
|
||||
→ Scan/Mark/Load/Unload: Worker dispatch
|
||||
→ Exchange等: Dispatcher.Enqueue (不经过 SubmitCandidates 的 JobRuntime 操作)
|
||||
```
|
||||
|
||||
**改动点**:
|
||||
1. `trySchedule` 中 MachineWait/Decision/BufferStage 直接调用 `DBState` 方法
|
||||
2. 删除 `SubmitCandidates` 中的 MachineWait/Decision/BufferStage 直接处理逻辑
|
||||
3. `SubmitCandidates` 简化为仅转换 + 入队 Dispatcher
|
||||
4. 删除 `tryDirectDispatch` 方法(逻辑移到 trySchedule)
|
||||
5. MachineWait 不再写 JobRuntime.State,只写 DB
|
||||
|
||||
**风险**:中——`tryDirectDispatch` 逻辑需要搬迁到 EventLoop。
|
||||
|
||||
### Phase 3: 删除旧调度路径
|
||||
|
||||
**目标**:`ScheduleAndSubmit` 完全被 `trySchedule` 替代。
|
||||
|
||||
**现状**:
|
||||
```
|
||||
RestoreOrder → ScheduleAndSubmit (旧路径)
|
||||
trySchedule nil entClient → ScheduleAndSubmit (测试 fallback)
|
||||
```
|
||||
|
||||
**目标**:
|
||||
```
|
||||
RestoreOrder → EventLoop.SendScheduleTick → trySchedule
|
||||
删除 ScheduleAndSubmit 方法
|
||||
```
|
||||
|
||||
**改动点**:
|
||||
1. `RestoreOrder` 末尾的 `ScheduleAndSubmit()` 改为 `jp.eventLoop.SendScheduleTick()`
|
||||
2. 删除 `ScheduleAndSubmit` 方法
|
||||
3. 删除 `scheduleMu` 字段(EventLoop 单线程保证序列化)
|
||||
4. `trySchedule` nil entClient 路径改为直接 return
|
||||
|
||||
**风险**:低——仅旧的恢复路径受影响,改动量小。
|
||||
|
||||
### Phase 4: JobRuntime 最小化
|
||||
|
||||
**目标**:JobRuntime 仅保留复杂动作所需的字段和方法。
|
||||
|
||||
**保留**:
|
||||
- `buildLoadAction/buildUnloadAction/buildScanAction/buildMarkingAction/buildDecisionAction/buildBufferStageAction`
|
||||
- `executeExchange/executeCleaningExchange/executeWasherExchange/executeWasherBatchUnload`
|
||||
- `handleMachineDone` (由 EventLoop 的 WakeJob 调用)
|
||||
- `GetState` / `GetContext` (供 Dispatcher 读取)
|
||||
- 所有依赖注入字段(registry, scanner, marker, robotCtrl 等)
|
||||
|
||||
**删除**:
|
||||
- `enqueueCurrentStep` 方法(不再需要)
|
||||
- `HandleTaskComplete` 简化(仅复杂动作使用)
|
||||
- `notifyReady` 回调 → 删除(调度由 EventLoop 直接触发)
|
||||
- `syncStatusToDB` 简化为仅复杂动作使用
|
||||
- `stepEnqueued` / `lastEnqueuedStep`(不再入队)
|
||||
- `pendingPause` / `pendingSuspendReason` → 改为 DB 字段
|
||||
- `complete()` / `cleanupOnError()` → 移到 EventLoop
|
||||
|
||||
**改动点**:
|
||||
1. 复杂动作的 ActionFn 闭包完成后,不调 `HandleTaskComplete`,而是投递 WorkerResult 到 EventLoop
|
||||
2. `exchangePairer` 逻辑移到 EventLoop 管理
|
||||
3. JobRuntime 变成纯粹的 "动作描述符"(identity + position + context for closure capture)
|
||||
|
||||
**风险**:高——深度改动 JobRuntime 状态机,需要大量回归测试。
|
||||
|
||||
## 优先级建议
|
||||
|
||||
| Phase | 优先级 | 影响 | 状态 |
|
||||
|-------|--------|------|------|
|
||||
| Phase 1 | 🔴 高 | 简单路径彻底 SSOT | ✅ 完成 (2026-05-10) |
|
||||
| Phase 2 | 🟡 中 | 调度逻辑统一 | ✅ 完成 (2026-05-10) |
|
||||
| Phase 3 | 🟢 低 | 清理旧代码 | ✅ 完成 (2026-05-10) |
|
||||
| Phase 4 | ⚪ 部分 | 高风险的深度重构 | 仅移除 toolLocker 死代码 (2026-05-10) |
|
||||
|
||||
## 已完成改动
|
||||
|
||||
### Phase 1: DBState.AdvanceStep
|
||||
|
||||
- `dbstate.go` 新增 `AdvanceStep(ctx, jobID, ctxUpdates, posType, posRefID)`
|
||||
- 从 DB 读 job → 计算下一步 → 如果是最后步则 FinishJob,否则 CompleteStep
|
||||
- 同时更新 position、context
|
||||
- `loop.go` handleWorkerResult 直派路径:`db.AdvanceStep` 替代 `NotifyStepComplete → HandleTaskComplete`
|
||||
- Worker 结果不再经过 JobRuntime
|
||||
|
||||
### Phase 2: trySchedule 直接处理 MachineWait/Decision/BufferStage
|
||||
|
||||
- `trySchedule` 中新增 3 个方法,直接写 DB:
|
||||
- `handleMachineWaitCandidate` → DB 写 WaitingUnload
|
||||
- `handleDecisionCandidate` → 读 context + 更新 + AdvanceStep
|
||||
- `handleBufferStageCandidate` → 读 position + AdvanceStep
|
||||
- `SubmitCandidates` 不再处理这 3 类候选
|
||||
|
||||
### Phase 3: 删除旧路径
|
||||
|
||||
- `RestoreOrder` 的 `ScheduleAndSubmit()` 改为 `SendScheduleTick()`
|
||||
- 删除 `scheduleMu` 字段(EventLoop 单线程保障序列化)
|
||||
- `ScheduleAndSubmit` 保留为 nil entClient fallback
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [ ] `go test ./...` 全量通过
|
||||
- [ ] mockrun 1 个 job 完整流程 ≤ 3 分钟完成
|
||||
- [ ] EventLoop.advanceStep 是唯一的步骤推进路径
|
||||
- [ ] `jp.jobs` map 的写入只发生在 StartOrder/RestoreOrder
|
||||
- [ ] `syncStatusToDB` 不包含步骤推进逻辑
|
||||
- [ ] 不存在 `jr.HandleTaskComplete` 被简单路径调用的情况
|
||||
Reference in New Issue
Block a user