principle-separate-before-serializing-shared-state
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSeparate Before Serializing Shared State
先分离,再序列化共享状态
When concurrent actors might share mutable state, first ask whether they truly need the same mutable object. If not, eliminate the sharing. When sharing is real, enforce serialization structurally: lockfiles, sequential phases, exclusive ownership. Instructions and conventions are not concurrency control.
Why: Concurrent writes to shared state create race conditions that are intermittent, hard to reproduce, and expensive to debug. Telling agents or goroutines to "take turns" does not work.
Pattern:
- Identify shared mutable state (files both read and write, branches both push to, APIs both define and consume).
- Default: eliminate the shared write target. Ask: do these actors need one canonical object, or are they publishing independent facts? Give each actor its own owned file, key, branch, or state directory, and merge only at the read/reporting boundary. Two workers writing their own field into one
lastXis still shared mutation;state.json+indexer-state.jsonis not.metrics-state.json - Only when one shared write target is a real invariant, serialize access structurally (lockfiles, sequential phases, single-writer actor, or atomic compare-and-swap). Treat "we need a lock" as a design smell to check, not as the default answer.
当多个并发参与者可能共享可变状态时,首先要问:它们是否真的需要同一个可变对象?如果不需要,就消除共享。当必须共享时,通过结构化方式强制序列化:锁文件、顺序阶段、排他所有权。仅靠指令和约定无法实现并发控制。
原因: 对共享状态的并发写入会导致竞态条件,这类问题间歇性发作、难以复现且调试成本高昂。仅仅告诉Agent或goroutine“轮流操作”是行不通的。
模式:
- 识别共享可变状态(同时读写的文件、共同推送的分支、同时定义和消费的API)。
- 默认方案:消除共享写入目标。问一问:这些参与者是需要一个标准对象,还是各自发布独立的信息?为每个参与者分配专属的文件、键、分支或状态目录,仅在读取/报告阶段进行合并。两个工作进程将各自的字段写入同一个
lastX仍属于共享变更;而state.json+indexer-state.json则不属于。metrics-state.json - 只有当必须保留单个共享写入目标时,才通过结构化方式序列化访问(锁文件、顺序阶段、单一写入者参与者或原子比较并交换操作)。将“我们需要锁”视为需要检查的设计异味,而非默认解决方案。