news 2026/8/2 5:16:26

持久化执行前置课(十):画出最小持久化内核,再开始写执行器

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
持久化执行前置课(十):画出最小持久化内核,再开始写执行器

上一篇为事件与逻辑加上版本契约,旧运行终于能够跨部署恢复。现在可以收束九篇原则:稳定身份标记同一件事,追加事件保存事实,纯决定产生命令,发件箱投递意图,幂等回执约束副作用,租约与预算控制恢复。

一、痛点:组件齐全仍可能边界混乱

团队很容易先选数据库、队列和编排框架,再把业务判断塞进 worker 循环。结果是历史读取、网络调用、状态推进和异常重试相互嵌套,任何一步都无法独立重放。最小内核不是功能最少的玩具,而是职责最少且边界可验证的结构。

二、原理:一个确定性核,两个持久化方向

内核读取事件历史,折叠出状态,再根据新事件产生新状态和命令。向内只追加事件,向外只写命令意图;活动执行器把命令变成回执事件。下面用纯内存数据展示一轮循环,刻意不在决定函数里执行命令。

fromdataclassesimportdataclass,replace@dataclass(frozen=True)classState:phase:str="new"token:str|None=None@dataclass(frozen=True)classMessage:kind:strdata:dictdefdecide(state:State,event:Message)->tuple[State,list[Message]]:ifstate.phase=="new"andevent.kind=="trip_requested":returnreplace(state,phase="locking"),[Message("lock_budget",{"activity_id":"act-1"})]ifstate.phase=="locking"andevent.kind=="budget_locked":returnreplace(state,phase="ready",token=event.data["token"]),[]raiseValueError(f"invalid:{state.phase}+{event.kind}")state=State()history=[]outbox=[]foreventin[Message("trip_requested",{}),Message("budget_locked",{"token":"B-7"}),]:state,commands=decide(state,event)history.append(event)outbox.extend(commands)print(event.kind,"=>",state.phase,[item.kindforitemincommands])print("history=",len(history),"outbox=",len(outbox),"token=",state.token)

输出:

trip_requested => locking ['lock_budget'] budget_locked => ready [] history= 2 outbox= 1 token= B-7

三、实现:用不变量先约束存储接口

在选择框架前,先写存储端口的契约测试:序号连续、期望版本冲突、事件与命令同事务、命令 ID 唯一、完成回执引用已有命令。示例验证最核心的守恒关系,任何阶段都不能凭空出现。

fromdataclassesimportdataclass@dataclass(frozen=True)classRecord:seq:intevent:strcommands:tuple[str,...]defvalidate(records:list[Record],completed:set[str])->None:known=set()forexpected,recordinenumerate(records,start=1):ifrecord.seq!=expected:raiseValueError("sequence_gap")forcommandinrecord.commands:ifcommandinknown:raiseValueError("duplicate_command")known.add(command)missing=completed-knownifmissing:raiseValueError(f"orphan_receipt:{sorted(missing)}")records=[Record(1,"trip_requested",("act-1",)),Record(2,"budget_locked",("act-2",)),Record(3,"flight_booked",()),]validate(records,{"act-1","act-2"})print("valid records=",len(records))try:validate(records,{"act-3"})exceptValueErroraserror:print("caught",error)

输出:

valid records= 3 caught orphan_receipt:['act-3']

四、踩坑:一开始就追求分布式规模

单机 SQLite 足以验证事务边界、重放和崩溃语义。过早引入多分区队列会把业务错误藏在基础设施噪声里。另一个坑是把快照当事实源;快照只是缓存,删除后必须能由事件重建。监控指标同样不能代替事件,指标可采样、可丢失,不适合裁决业务状态。

最小内核也要从第一天保存模式版本、逻辑版本、活动 ID 和停止原因,否则以后补字段无法解释旧记录。安全边界应默认拒绝未知事件和未知版本。人工操作通过命令进入同一事件链,而不是提供一个绕过历史的“强制改状态”按钮。

五、验证:先证明纯核,再连接数据库

验收顺序应是状态转移表、历史重放、非法事件、命令稳定性,然后才是数据库事务、队列重复和进程崩溃。每加入一种基础设施,都保留前一层快速测试。最终从空库执行一条旅行历史,关闭进程、重新打开并重放,所得状态和命令摘要必须一致。

至此,090 的证据包不再只是任务终点:它启发了持久化执行从一开始就保存可验证事实。这十篇完成了从证据消费到内核蓝图的桥接。下一篇将真正从零实现miniflow,先把旅行预订工作流写成无数据库、无网络的纯状态机,再逐步为它接上持久化能力。

参考来源

  • Temporal:核心应用结构
  • Martin Fowler:Functional Core, Imperative Shell
  • SQLite:事务

👍 觉得有用就点个赞 + 收藏,方便回头查阅;有疑问直接在评论区留言,我看到都会回。

🚀 本文属于《持久化执行前置课》系列,持续更新,关注不迷路。

📌 文章里的代码都能直接跑。想要可直接 clone 的完整工程 + 配套部署脚本 / 踩坑清单?评论一声或发邮件到cj2664@qq.com,我免费发你。
如果你正好在做类似系统、或有工程化难题想找人做,也欢迎邮件聊一句——我按实际情况评估,能落地的就接单或出方案。评论和邮件都能直接找到我,不用跳别的平台。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/2 5:16:14

DsHidMini:内核驱动实现老旧USB设备全局兼容Xbox手柄协议

1. 项目概述:DsHidMini是什么,以及它解决了什么问题如果你玩过一些老游戏,或者折腾过一些特殊的硬件外设,可能会遇到一个头疼的问题:你的新手柄、新键盘,电脑就是不认。尤其是在Windows 10/11系统下&#x…

作者头像 李华
网站建设 2026/8/2 5:14:44

Windows原生SSH服务器部署与配置全指南:从原理到实战

1. 项目概述:为什么要在Windows上折腾SSH? 如果你是一个习惯了Linux/macOS终端操作,或者需要频繁管理远程服务器的开发者,突然切换到Windows环境,最头疼的莫过于那个“原生”的命令行体验。传统的远程桌面(…

作者头像 李华
网站建设 2026/8/2 5:13:09

从零打造MP3播放器:Arduino/ESP32硬件解码与嵌入式音频开发实践

1. 项目概述:从“听个响”到“玩出花”,聊聊DIY MP3播放器的那些事儿十几年前,MP3播放器还是人手一个的数码潮品,如今它似乎被手机“集成”了。但对我们这些喜欢动手折腾的人来说,用一块小小的开发板,从零开…

作者头像 李华
网站建设 2026/8/2 5:12:32

SAP表缓存深度解析:从原理到实战的性能优化指南

1. 项目概述:为什么SAP表缓存是性能优化的基石在SAP项目实施和运维的日常里,性能问题就像房间里的大象,你无法忽视它。无论是财务月结时FICO模块的报表跑得让人心焦,还是MM模块物料主数据查询时那转个不停的沙漏,背后往…

作者头像 李华
网站建设 2026/8/2 5:12:29

AI药物发现:从蛋白-配体相互作用到靶向分子生成的技术实践与反思

1. 项目概述:当AI开始“画靶心”最近在翻看一些前沿的学术动态和开源项目时,一个挺有意思的讨论引起了我的注意。它来自一篇观点性文章,标题直译过来大概是“审视基于靶标的从头分子生成:理性设计,抑或射箭画靶&#x…

作者头像 李华
网站建设 2026/8/2 5:10:58

天线核心参数全解析:从频率、增益到VSWR,硬件工程师选型指南

1. 天线是什么?为什么参数如此重要?如果你拆开过家里的无线路由器,或者仔细观察过手机顶部那条细细的缝隙,那你已经见过天线了。天线,这个看似简单的金属片或线圈,是我们无线世界的“嘴巴”和“耳朵”。它负…

作者头像 李华