私は、Googleドキュメントと同様の機能(複数の人が同時に作業できるようにする)を備えた独自のJavascriptエディターを作成することをいじくり回してきました。私が理解していないことの1つ:
ユーザーAとユーザーBが10msのネットワーク遅延で互いに直接接続されているとしましょう。エディターが(ドキュメントが理解しているように)差分システムを使用していると仮定します。このシステムでは、編集は「インデックス3に「テキスト」を挿入」のように表され、差分にはタイムスタンプが付けられ、すべてのクライアントによって時系列で適用されます。
「xyz123」というテキストを含むドキュメントから始めましょう。
ユーザーAはタイムスタンプ001msでドキュメントの先頭に「abc」と入力し、ユーザーBはタイムスタンプ005msで「xyz」と「123」の間に「hello」と入力します。
どちらのユーザーも、結果が「abcxyzhello123」になることを期待しますが、ネットワーク遅延を考慮すると次のようになります。
もちろん、「abchelloxyz123」は「abc」と同じではありません。 xyzhello123 "
文字通りすべてのキャラクターに独自のIDを割り当てる以外に、Googleがこの問題を効果的に解決する方法を想像することはできません。
私が考えたいくつかの可能性:
http://www.waveprotocol.org/whitepapers/operational-transform を読んでいますが、この問題を修正するためのあらゆるアプローチを聞きたいと思います。
シナリオのトポロジとさまざまなトレードオフに応じて、レプリカの同時変更を実現するためのさまざまな可能性があります。
最も一般的なシナリオは、すべてのクライアントが通信する必要がある中央サーバーです。
サーバーは、各参加者のドキュメントがどのように見えるかを追跡できます。次に、AとBの両方が、変更を含む差分をサーバーに送信します。次に、サーバーは変更をそれぞれの追跡ドキュメントに適用します。次に、3方向マージを実行し、変更をマスタードキュメントに適用します。次に、マスタードキュメントとトラッキングドキュメントの差分をそれぞれのクライアントに送信します。これは 差分同期 と呼ばれます。
別のアプローチはoperation(al)変換と呼ばれ、従来のバージョン管理システムでのリベースに似ています。中央サーバーは必要ありませんが、参加者が3人以上の場合は、中央サーバーを使用すると作業がはるかに簡単になります( OT FAQ を参照)。要点は、ある編集で変更を変換して、別の編集の変更がすでに行われたと編集が想定するようにすることです。例えば。 Aは、Bの編集insert(3, hello)
をその編集insert(0, abc)
に対して変換し、結果はinsert(6, hello)
になります。
リベースとOT)の違いは、異なる順序で編集を適用した場合、リベースは一貫性を保証しないことです(たとえば、BがAの編集を逆にリベースした場合、これは一方、OT)の約束は、適切な変換を行う場合に任意の順序を許可することです。
ピアツーピアシナリオを処理できるOTアルゴリズムが存在します(制御層での実装の複雑さの増加とメモリ使用量の増加のトレードオフがあります)。単純なタイムスタンプの代わりに、 バージョンベクトル を使用して、編集の基になっている状態を追跡できます。次に(OTアルゴリズム、具体的には変換プロパティ2)の機能に応じて)、受信した編集を次のように変換できます。受信した順序に合わせるか、バージョンベクトルを使用して編集に半順序を課すことができます。この場合、編集を元に戻して変換することにより、履歴を「書き換え」て、課された順序に従う必要があります。バージョンベクトルによって。
最後に、 [〜#〜] crdt [〜#〜] に基づくWOOT、Treedoc、Logootと呼ばれるアルゴリズムのグループがあり、操作を可能にする特別に設計されたデータ型で問題を解決しようとします。通勤するので、それらが適用される順序は重要ではありません(これは、各文字のIDの考え方に似ています)。ここでのトレードオフは、メモリ消費と操作構築のオーバーヘッドです。