私は、Google Docs に似た機能 (複数の人が同時に作業できるようにする) を備えた、独自の Javascript エディターを作成することをいじっています。私が理解していないことの1つ:
ユーザー A とユーザー B が 10 ミリ秒のネットワーク遅延で互いに直接接続されているとします。私は、編集が「インデックス 3 に「テキスト」を挿入」のように表される diff システム (Docs が行っていることを理解している) をエディターが使用していると仮定しています。
「xyz123」というテキストを含むドキュメントから始めましょう。
ユーザー A はタイムスタンプ 001ms でドキュメントの先頭に「abc」と入力し、ユーザー B はタイムスタンプ 005ms で「xyz」と「123」の間に「hello」と入力します。
どちらのユーザーも、結果が「abcxyzhello123」になることを期待しますが、ネットワークの遅延を考慮すると、次のようになります。
- ユーザー B は、時間 011ms にユーザー A の「インデックス 0 に 'abc' を挿入」の編集を受け取ります。時系列の順序を維持するために、ユーザー B はユーザー B のインデックス 3 での挿入を元に戻し、ユーザー A の「abc」をインデックス 0 で挿入し、次にユーザー B のインデックス 3 での挿入を再挿入します。これは現在「abc」と「xyz」の間にあります。 、」したがって、「abchelloxyz123」が得られます
- ユーザー A は、時間 015ms にユーザー B の「インデックス 3 に「hello」を挿入」の編集を受け取ります。ユーザー B の挿入がユーザー A の後に行われたことを認識し、インデックス 3 (現在は "abc" と "xyz" の間) に "hello" を挿入するだけで、"abchelloxyz123" となります。
もちろん、「abchello xyz123」は「 abc xyz hello 123」と同じではありません。
文字通りすべてのキャラクターに独自の一意の ID を割り当てる以外に、Google がこの問題を効果的に解決する方法を想像することはできません。
私が考えたいくつかの可能性:
- ユーザー B が編集前に挿入ポイントを 1 ミリ秒移動した場合、まったく同じ問題が発生することを除いて、差分を含むインデックスを送信する代わりに挿入ポイントを追跡することは機能します。
- ユーザー B に、「'xyz' の後に挿入」などの情報を diff で送信してもらい、ユーザー A がこれが発生したことをインテリジェントに認識できるようにすることもできますが、ユーザー A がテキスト「xyz」を挿入するとどうなるでしょうか。
- ユーザー B は、これが発生したことを認識し (ユーザー A の diff を受信し、それが競合していることを確認すると)、ユーザー B の編集を元に戻す diff と、ユーザー B の "hello" "abc".length インデックスをさらに挿入する新しい diff を送信します。右。これに関する問題は、(1) ユーザー A がテキストに「ジャンプ」を表示すること、および (2) ユーザー A が編集を続ける場合、ユーザー B は継続的に差分を修正する必要があることです。修正する必要があり、複雑さが指数関数的に増加します。
- ユーザー B は、最後に受信したタイムスタンプ付きの diff が -005ms か何かであるというプロパティを diff と共に送信できます。その後、A は B がその変更について知らなかったことを認識し (A の diff は 001ms であったため)、競合の解決を行うことができます。問題は、(1) ほとんどのコンピューターの時計がミリ秒単位で正確ではないことを考慮すると、すべてのユーザーのタイムスタンプがわずかにずれることと、(2) ユーザー A との遅延が 25 ミリ秒でユーザー B との遅延が 2 ミリ秒の 3 番目のユーザー C が存在する場合、ユーザー C が -003ms で「x」と「y」の間にテキストを追加すると、ユーザー B はユーザー C の編集を参照点として使用しますが、ユーザー A はユーザー C の編集については知りません (したがって、ユーザー B の参照点) 22msまで。共通のサーバーを使用してすべての編集にタイムスタンプを付ければ、これは解決できると思いますが、それはかなり複雑なようです。
- 各キャラクターに一意の ID を与え、インデックスの代わりにそれらの ID を使用することもできますが、それはやり過ぎのように思えます...
http://www.waveprotocol.org/whitepapers/operational-transformを読んでいますが、この問題を解決するためのあらゆるアプローチを聞きたいです。