← [ BACK_TO_NOTES ]

专题归档 · 2026 年 3 月(编辑分组,非实际写作日期)

MemoFlow:启用 Routine 后,Scheduler 和 Notification 怎么保持一致?

一次跨模块提醒一致性问题,从旧 ScheduleTask 假设演变为 Routine/Scheduler/Notification。

当时问得很具体

旧笔记保留了一段直接提问:在采用 DDD、Reminder、Schedule、Notification 通过事件总线连接的项目里,启用提醒后应该建立定时任务,触发时再生成通知,这一整条链怎么测试,才能确信不会缺事件、重复执行?

模块职责分开之后的代价

“Reminder 保存成功”并不自动等于 Scheduler 已经订阅并保存下一次触发,更不等于 Notification 已经到达。原材料后面有关于 Outbox、幂等键、关联 ID 及跨模块集成测试的长篇 AI 答复,这些是候选设计,不能直接写成项目当年已部署了 Outbox。

我保留的问题

这段经历最有价值的部分是最初的业务不变量:提醒被启用之后,最终应该对应正确的调度计划;同一次调度不应导致重复通知;关闭提醒之后,旧任务也不能继续误触发。

我现在会先把它们写成测试场景,而不是直接选择某个消息队列或 Outbox 框架:

行为需要观察的业务结果
启用 Reminder对应 ScheduleTask 最终存在,时间配置一致
重复接收同一个启用事件不会生成两个等价调度任务
禁用 Reminder已存在的 ScheduleTask 进入 disabled 状态
Schedule 触发成功Notification 获得一次可识别的触发请求
消费者暂时失败 / 重试能恢复推进,但不会重复产生业务副作用

测试层次也要分开:Reminder 的单元测试只判断自身状态和产生的事件,Schedule Handler 测试验证幂等处理,最后才写跨模块集成测试验证完整链路。真正需要分布式可靠交付时,再考虑 Outbox、持久重试或去重键。

这些是我从原始问题推导出的验证设计,不等于旧 DailyUse 在当时已经实现、上线或通过了这一整套测试。

后来这条链路怎样收敛

MemoFlow 后来的模型不再把历史 ReminderTemplate → ScheduleTask → Notification› 当成当前的产品接口。提醒业务已转为 Routine,Routine 拥有触发规则和执行事实;它通过 ScheduledIntent / SchedulingPort.reconcile› 请求 Scheduler 唤醒,Scheduler 只管理 ScheduledInvocation / InvocationAttempt› 的可靠执行;Notification 则拥有 NotificationRequested›、Fact 和 Dispatch Outbox。

Routine owner:长期配置 / 触发事实
      ↓ reconcile
Scheduler:计划唤醒 / lease / retry
      ↓ handler
Notification:Fact 幂等创建 / 投递尝试

原来的不变量仍有效,只是验证对象需要换成当前 contract。启用/禁用 Routine 要测试是否正确 reconcile,而不是检查已退休的 ScheduleTask 表;重复触发应检查 Routine occurrence 和 Notification 的各自幂等键;显示了 Notification Fact 也不等于某个桌面渠道投递成功。

这些变化说明可靠性不能靠单个“发事件成功”断言:应分别验证业务状态、调度意图、后台执行、通知事实和设备投递五段边界。旧文章中的表格保留为当时的讨论记录,不应直接作为今天的自动化验收脚本。

创建于 2026/3/5 更新于 2026/10/17
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本