Почему операционная трансформация Документов Google приводит к ошибкам на стороне удаления?
Попробовал сегодня этот эксперимент: открыл два оффлайн-редактора для документа Google. В одном я выделил первое слово. Во втором я его удалил. Независимо от того, какой клиент я включаю первым, слово всегда удаляется.
Прежде всего, почему это так - мое понимание операционной трансформации заключается в том, что порядок имеет значение? В простом примере двух людей, набравших "a" и "b" соответственно, если сервер сначала получает "a", он принудительно выведет "ab", преобразовав событие "b" второго человека в "pass one space", затем добавьте b "событие, и наоборот.
Во-вторых, если заказ не имеет значения, есть ли технические причины, по которым Google Docs решил ошибиться на стороне удаления? Или причины во многом просты для пользователей?
3 ответа
Вот (спустя 5 лет, я знаю) графическое объяснение происходящего (что на самом деле описывает @osma, но графически объясняет):
Когда вы выделяете строку в GDocs, вы фактически оборачиваете строку в контейнер, предположительно <strong></strong>
но они могут использовать любой другой синтаксис. Для простоты давайте просто скажем, что выделение жирным шрифтом строки требует "+" в начале слова. Так что текст "Lorem Ipsum" станет lorem +ipsum
и не lorem <something>ipsum<something>
1
И у Алисы, и у Боба начальный текст "Lorem ipsum"
2
Затем Боб удаляет "ipsum". Обратите внимание, что он отправляет на сервер набор изменений retain(6), delete(5)
, Набор изменений по сути является патчем, и его структура, скорее всего, основана на этой библиотеке.
3
И Алиса жирным шрифтом "ipsum" (добавив "+"). Обратите внимание на то, что она отправляет ревизию retain(6), insert(+), retain(5)
4
Оба набора изменений отправляются на сервер, который еще ничего не знает об этих наборах изменений.
5
Предполагая худший сценарий: сначала приходит пакет Боба, а затем слово будет удалено. (Другой сценарий очевиден).
6
Когда приходит пакет Алисы, он добавляет только "+" к тексту, потому что то, что она послала, является всего лишь набором изменений.
7
Оба текста - это наборы изменений, транслируемые клиентам. Это первый.
8
9
После внесения этих изменений в исходный текст вы получите "Lorem +". Этот символ позже стирается обычным чистым процессом HTML, который удаляет любой тег с форматом <tag></tag>
,
Чтобы проверить это демо, перейдите по ссылке: http://operational-transformation.github.io/visualization.html. Там вы можете играть с текстами и пакетами, как они отправлены / получены.
OT не пытается различить намерение, он применяет преобразования в порядке, который дает последовательный результат. Когда вы применяете оба этих изменения к документу, не имеет значения, в каком порядке вы применяете их.
"первая секунда" -> "первая секунда" -> "первая"
"первая секунда" -> "первая" -> "первая"
Во втором потоке полужирная операция выполняется для строки нулевой длины.
Это тот же самый результат, который вы получите, если в одном из этих документов вы выделите курсивом второе слово: конечным результатом будет "первая секунда" независимо от порядка преобразования. Удалить преобразование ничем не отличается.
Это не вопрос ошибки на стороне удаления.
В тех случаях, когда оба клиента имеют действительное равенство, но разные версии правдивости, Документы Google должны выбрать поддержку одной версии или заставить пользователей разрешать конфликты, что по своей сути сложно и трудно объяснить.
Таким образом, "правда" для Google Docs - это согласованность документа, а не разборчивость намерений. А согласованность лучше всего достигается путем уничтожения информации - своего рода тенденция к энтропии.
Все это в основном мой полуфилософский BS, хотя...