92785eb3e1
design 0003 的否决方案一节承诺过「显式命名的、明确不提供恢复的内存实现」,那个实现一直 没写,migrations/dissect.md 还专门登记着「不要照那句话去找一个不存在的类」。 **名字取 VolatileRunStore 不取「不提供恢复」**:一个真的读不回自己写过的东西的存储过不了 自家的契约套件(套件第一条要的就是「写进去的意图读得回来」),而这一层的准入标准就是那套 套件。一个过不了自家准入标准的实现不该存在。它不提供的是跨进程恢复,Volatile 说的正是这 件事。 桶里存编码后的载荷、读的时候才解码,两个方向的别名都堵上:调用方写完再改自己手里那个 dict 改不到日志,读回来的日志被就地改动也污染不了存储本身。落盘那个实现每次重新解析文件,天然 如此,这个实现靠同一条路径对齐它。**写入只编码不解码**——落盘那边写的时候只做 json.dumps, 一条字段类型不对的记录写得进去、读的时候才炸,两边现在一致。 两张平行的表(记录类→标签、标签→解码器)合成一张三元组再派生视图。加上易失实现要用的第三 张视图之后,三张表之间那个谁也不检查的一致性要求就不可能被违反了。
20 lines
1.3 KiB
Python
20 lines
1.3 KiB
Python
"""存储接缝的两个实现:一个逐行追加进本地文件,一个只留在进程内存里。
|
||
|
||
**这一层公开,但不进 `polyloop/__init__.py`**,必须显式 import(`0003` 决策八第 9 条)。存储
|
||
是必填的装配项,库不给默认值:顺手提供一个默认实现等于替所有下游选了日志落在哪儿,而那是
|
||
每个项目自己的运维决定。调用方要么从这里挑一个,要么自己写一个。
|
||
|
||
**关系数据库那一种形态本库不提供。** 表结构、事务边界、连接管理都在项目那边,库替它写一个
|
||
通用实现只会写出一个谁都不合用的。存储接缝的意义就是让它自己实现,而契约套件
|
||
(`polyloop.testing`,见 `research-wiki/design/0014-contract-suite-distribution.md` 决策一)
|
||
是它的准入标准:那套用例只说行为、不碰形态,跑全绿就算合格。
|
||
|
||
**这一层也不提供「把日志转成别的格式」「按时间范围查」这类操作。** 存储接缝上多一个方法,就是
|
||
给每一个下游实现多加一份永久要求,而这些事拿 `read_log` 读回来的日志在库外面做即可。
|
||
"""
|
||
|
||
from polyloop.stores._jsonl import RECORD_KEY, JsonlRunStore
|
||
from polyloop.stores._volatile import VolatileRunStore
|
||
|
||
__all__ = ["RECORD_KEY", "JsonlRunStore", "VolatileRunStore"]
|