Hashimoto   Baku

Hashimoto   Baku

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 コレクション(サーバー専用)を別途保持する。ページが削除されると:

  1. tombstones に最後の content スナップショットと deletedAt を記録
  2. 通常の doc.remove() で RxDB 上の soft delete を実行

Pull 時は通常ページと tombstone をタイムスタンプ順にマージして返却する。これにより他のクライアントが削除を検知し、ローカルに反映できる。

Push 時にクライアントが削除済みページを書き込もうとすると、tombstone の存在で
conflict が検出され、サーバーの削除状態が優先される。