garden.oooレプリケーションのマージ戦略
このドキュメントは データアーキテクチャ の「Local DB ↔ Remote DB」同期の詳細。
概要
各ブラウザはローカルの RxDB (IndexedDB) を持ち、HTTP pull/push を介して
中央の RxDB (MongoDB) サーバーと同期する。さしあたり共同同時編集は想定せず、単一ユーザーが一度に一つのデバイスで操作する前提。
戦略: Server Wins
push 時に conflict が検出された場合、サーバーの状態を正とする。クライアントはサーバーの状態を受け入れ、ローカルの差分を破棄する。
Conflict 検出 (Push)
各 push 行には assumedMasterState(クライアントが想定するサーバーの現在状態)が付与される。サーバーはこれを実際の状態と比較する:
- 一致 → 書き込みを受理
- 不一致 → 書き込みを拒否し、実際のサーバー状態を conflict として返却
クライアントの conflict handler はサーバー状態を採用して resolve する。
削除と Tombstone
RxDB の Collection.find() / findOne() は内部で _deleted: {$eq: false} を強制付与するため、soft delete されたドキュメントを通常のクエリで取得できない。
この制約を回避するため、サーバー側に tombstones コレクション(サーバー専用)を別途保持する。ページが削除されると:
tombstonesに最後の content スナップショットとdeletedAtを記録- 通常の
doc.remove()で RxDB 上の soft delete を実行
Pull 時は通常ページと tombstone をタイムスタンプ順にマージして返却する。これにより他のクライアントが削除を検知し、ローカルに反映できる。
Push 時にクライアントが削除済みページを書き込もうとすると、tombstone の存在で
conflict が検出され、サーバーの削除状態が優先される。