Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

principle-separate-before-serializing-shared-state

先分离,再串行化共享状态

When concurrent actors might share mutable state, first ask whether they 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.

并发 actor 可能共享可变状态时,先问它们是否需要同一可变对象。不需要就消除共享。共享是真的,就用结构强制串行:锁文件、顺序阶段、独占所有权。文字指示和约定不是并发控制。

Why: Concurrent writes to shared state create race conditions that are intermittent, hard to reproduce, and expensive to debug.

为什么: 对共享状态的并发写会造成间歇、难复现、调试昂贵的竞态。

Pattern:

模式:

  1. Identify shared mutable state (files both read and write, branches both push to, APIs both define and consume).

  2. 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 lastX field into one state.json is still shared mutation. indexer-state.json + metrics-state.json is not.

  3. 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.

  4. 识别共享可变状态(双方都读写的文件、双方都 push 的分支、双方都定义并消费的 API)。

  5. 默认:消除共享写目标。 问:这些 actor 需要一个规范对象,还是在发布独立事实?给每个 actor 自己拥有的文件、key、分支或状态目录,只在读/汇报边界合并。两个 worker 往同一个 state.json 写各自的 lastX 字段,仍是共享变异。indexer-state.json + metrics-state.json 不是。

  6. 只有单一共享写目标是真不变量时,才用结构串行访问(锁文件、顺序阶段、单写者 actor,或原子 compare-and-swap)。把「我们需要一把锁」当要检查的设计异味,不当默认答案。