Files
huachuang/docs/superpowers/specs/2026-08-03-task-callback-mode-design.md

4.5 KiB
Raw Blame History

任务完成与取消双通道回调设计

目标

任务模块根据 YAML 配置选择 MQ 异步或 Feign 同步方式通知 LMS/WMS 执行完成、取消业务;业务处理成功后,两条链路都由 Task 服务统一把任务从回调待处理状态推进到最终完成或取消状态。

当前问题

  • TransportTaskOperationManager#handleFinishedhandleCancelled 固定发布 RocketMQ 消息,无法切换为同步 Feign。
  • LMS/WMS 的 MQ Consumer 调用 AbstractTask#doHandleFinishdoHandleCancel 后没有回调 Task任务停留在 FINISHED_CALLBACK_PENDINGCANCEL_CALLBACK_PENDING
  • TransportTaskCallbackServiceImpl 使用 %03d 格式化字符串状态码,回调处理存在运行时类型异常。
  • TaskCommonApi 只暴露取货、进出等动作,没有完成和取消接口。

配置

在 Task 服务 YAML 中增加必填配置:

nl:
  task:
    callback-type: mq

允许值为 mqfeign。使用枚举解析配置;配置缺失或值非法时启动失败,不做静默兜底。默认项目配置使用 mq,保持现有部署行为。

执行链路

MQ 异步模式

  1. Task 将任务置为对应的回调待处理状态,并把 callbackStatus 置为 PENDING
  2. 当前事务提交后发布完成或取消消息。
  3. LMS/WMS Consumer 校验任务仍处于当前事件对应的待处理状态,然后路由到 AbstractTask 子类执行业务。
  4. 业务成功后Consumer 写入带有效期的 Redis 成功标识,再通过 TransportTaskApi.receiveCallbackResult 回调 SUCCESS若成功回调失败MQ 重试时只重试回调,不重复执行业务。
  5. Task 的统一回调服务把任务更新为 FINISHEDCANCELLED,并把 callbackStatus 置为 SUCCESS
  6. 业务异常时Consumer 尝试回调 FAILED 记录错误与重试次数,再重新抛出异常,让 MQ 执行重试。

Feign 同步模式

  1. Task 将任务置为对应的回调待处理状态,并把 callbackStatus 置为 PENDING
  2. Task 根据 ownerServiceTaskCommonApiFactory 获取 LMS/WMS Feign Client。
  3. 调用新增的 doHandleFinisheddoHandleCancelled,业务服务通过 TaskFactory 路由到相同的 AbstractTask 子类。
  4. Feign 返回成功后Task 直接调用统一回调服务,以相同规则更新最终状态。
  5. Feign 返回失败或抛出异常时不进入最终状态,异常沿现有任务操作链路上抛。

接口与数据

  • TaskCommonApi 增加 doHandleFinisheddoHandleCancelled
  • 两个接口继续复用 TaskStatusCallApiReqDTO,携带任务标识、业务归属、业务标识、处理器编码和 payload。
  • 同步与异步链路都复用 TaskCallbackResultReqDTOTransportTaskCallbackService 完成最终状态收口。
  • eventId 使用任务 ID 与事件类型组成的稳定值Task 按当前 pending 状态校验 eventId拒绝延迟或错序事件推进错误终态。

幂等与错误处理

  • Task 已处于 FINISHEDCANCELLED 时忽略重复成功回调。
  • 只有 FINISHED_CALLBACK_PENDING 能推进到 FINISHED,只有 CANCEL_CALLBACK_PENDING 能推进到 CANCELLED
  • MQ 重复消息在消费前查询 Task 状态;状态已不匹配时直接跳过。
  • MQ 业务成功后使用七天 Redis 标识隔离业务执行与 Task 成功回调重试;成功回调完成后删除标识。
  • Feign CommonResult 必须调用 getCheckedData 或检查 isSuccess,业务失败不允许误更新最终状态。
  • MQ 回调失败不吞掉业务异常,保留 RocketMQ 重试能力。
  • 任务状态分布式锁延迟到本地事务完成后释放,避免提交前窗口发生并发重复处理。

验证

  • Spring 集成测试验证 execute starter 的完成、取消 Feign 入口能正确路由到任务处理器。
  • 编译 execute starter、task-api、task-server、lms-server、wms-server验证跨模块接口一致。
  • 检查 MQ 成功回调和 Feign 成功返回最终都进入统一状态处理服务。

一致性边界

  • MQ 和 Feign 均向 AbstractTask 透传稳定的 eventIdeventType,业务处理器应以该事件标识在业务数据库中实现幂等。
  • Redis 成功标识可以避免“业务已成功、Task 成功回调失败”时重复执行业务但不能覆盖业务事务提交后、Redis 标识写入前进程崩溃的极小窗口,因此业务数据库幂等仍是最终保障。
  • Feign 调用与 Task 本地事务不构成分布式事务;远端成功后若本地事务回滚,重试仍依赖上述事件幂等。