principle-separate-before-serializing-shared-state

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

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.
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.
当并发执行者可能共享可变状态时,首先询问它们是否真的需要使用同一个可变对象。如果不需要,就消除共享。当共享确实存在时,从结构上强制串行化访问:使用锁文件、顺序执行阶段或独占所有权。口头指令和约定并不能构成并发控制。
原因: 并发写入共享状态会引发竞态条件。这类问题具有偶发性、难以复现,且调试成本高昂。
模式:
  1. 识别共享的可变状态(多个执行者都会读取和写入的文件、都会推送的分支、都会定义和使用的 API)。
  2. 默认做法:消除共享写入目标。 询问:这些执行者需要一个唯一的权威对象,还是在发布彼此独立的事实?为每个执行者分配其独占拥有的文件、键、分支或状态目录,并且只在读取或报告边界进行合并。两个 worker 将各自的
    lastX
    字段写入同一个
    state.json
    ,仍然属于共享变更;使用
    indexer-state.json
    和
    metrics-state.json
    则不属于。
  3. 仅当单一共享写入目标确实是必须满足的不变量时,才从结构上串行化访问(使用锁文件、顺序执行阶段、单写入者执行者或原子 compare-and-swap)。不要默认认为“需要加锁”,而应将其视为一个需要审查的设计异味。