HTTP 离线订单固定轮询设计
目标
HTTP 离线订单补传发生可重试失败时,不再返回 Result.retry(),避免 WorkManager 进入指数退避。补传继续沿用现有 180 秒 Alarm 周期。
范围
- 仅调整 HTTP 补传 Worker。
- 保留 MQTT 补传逻辑不变。
- 保留现有订单状态、原子抢占、10 分钟上传中状态恢复和三态回执策略。
- 不增加联网恢复后的即时上传。
- 不增加 WorkManager 网络约束。
- 不调整单轮上传数量及顺序。
调度设计
- 3 分钟 Alarm 收到 HTTP 补传信号后,先安排下一次 3 分钟 Alarm,再尝试创建唯一的
UploadOrderWorker。
- 如果上一轮 Worker 仍在运行,
ExistingWorkPolicy.KEEP 忽略本轮新 Worker;已经安排的下一次 Alarm 不受影响。
- Worker 启动后先判断网络状态。
- 无网络时不遍历订单、不发起 HTTP 请求,记录日志并返回
Result.success()。
- 有网络时沿用现有逐笔上传流程。
- 单笔发生订单级可重试失败时,将订单从上传中恢复为待上传,并继续处理本轮其他订单。
- 发生网络异常、HTTP 异常等传输级失败时,将当前订单恢复为待上传并立即结束本轮,避免继续请求剩余积压订单。
- Worker 的所有结束路径均返回
Result.success(),不再由 Worker 安排 Alarm,也不进入 WorkManager 指数退避。
- 新版本使用新的唯一任务名,并取消旧的
upload_offline_orders 任务,避免升级前已进入退避的任务继续阻塞固定轮询。
状态边界
1:待上传,下轮继续提交。
4:上传中,用于数据库原子抢占。
9:服务端确认成功,补传完成。
3:服务端明确业务失败,维持现有策略,不再重试。
本次不改变上述状态含义。
异常处理
- 无网络:本轮直接结束,由已续排的 Alarm 在 3 分钟后再检查。
- 网络或 HTTP 传输失败:恢复当前订单为状态
1 并结束本轮。
- 服务端订单级可重试失败:恢复当前订单为状态
1,继续处理其他订单。
- 明确业务失败:更新为状态
3,不再重试。
- 成功但本地更新失败:恢复为状态
1,3 分钟后重试。
- Worker 内部未预期异常:保持现有单笔兜底逻辑,确保已抢占订单恢复为状态
1。
验收标准
- HTTP 补传路径不再返回
Result.retry()。
- 连续失败时,相邻补传调度仍由 180 秒 Alarm 驱动,不出现 WorkManager 指数退避。
- 无网时不逐笔请求积压订单。
- 恢复网络后无需即时触发,最迟在下一次 3 分钟轮询中开始补传。
- HTTP 成功、可重试失败、明确业务失败的订单状态与当前策略一致。
- MQTT 补传行为不受影响。
- 上一轮超过 180 秒时,新 Worker 不并发执行,后续 Alarm 仍持续存在。
- 升级前遗留的指数退避任务不会阻塞新固定轮询任务。
验证方案
- 单元测试:验证补传轮次结果策略始终选择固定轮询,不选择 WorkManager 重试。
- 静态检查:确认
UploadOrderWorker 不再包含 Result.retry() 返回路径。
- 构建检查:执行项目对应的 Java 编译或单元测试任务。
- 日志检查:确认 Alarm 在启动 Worker 前已经续排,传输失败日志会结束当前轮次。