Сервер документов:Обработка одновременных сохранений

StackOverflow https://stackoverflow.com/questions/9675

  •  08-06-2019
  •  | 
  •  

Вопрос

Я реализую сервер документов.В настоящее время, если два пользователя открывают один и тот же документ, затем изменяют его и сохраняют изменения, состояние документа будет неопределенным (либо изменения первого пользователя сохраняются навсегда, либо изменения второго).Это совершенно неудовлетворительно.Я рассмотрел два варианта решения этой проблемы:

Первый — заблокировать документ, когда он открыт кем-то в первый раз, и разблокировать его, когда он будет закрыт.Но если сетевое соединение с сервером внезапно прервется, документ останется в навсегда заблокированном состоянии.Очевидным решением является регулярная отправка пингов на сервер.Если сервер не получает K пингов подряд (K > 1) от конкретного клиента, документы, заблокированные этим клиентом, разблокируются.Если этот клиент появится снова, документы снова блокируются, если их еще кто-то не заблокировал.Это также может помочь, если клиентское приложение (работающее в веб-браузере) неожиданно завершает работу, что делает невозможным отправку на сервер сигнала «Выход, разблокировка моих документов».

Второй — хранить несколько версий одного и того же документа, сохраненных разными пользователями.Если в документ вносятся изменения в быстрой последовательности, система предложит либо объединить версии, либо выбрать предпочтительную версию.Чтобы оптимизировать пространство для хранения, следует сохранять только различия документов (точно так же, как программное обеспечение для контроля версий).

Какой метод выбрать, учитывая, что соединение с сервером может иногда быть медленным и неотзывчивым?Как следует определять параметры (интервал пинга, интервал быстрой последовательности)?

P.S.К сожалению, я не могу хранить документы в базе данных.

Это было полезно?

Решение

Мое предложение будет чем-то вроде вашего первого.Когда первый пользователь (Боб) открывает документ, он получает блокировку, чтобы другие пользователи могли только читать текущий документ.Если пользователь сохраняет документ во время его использования, блокировка сохраняется.Только когда он выходит из документа, он разблокируется, и другие люди могут его редактировать.

Если второй пользователь (Кейт) откроет документ, в то время как Боб блокирует его, Кейт получит сообщение о том, что документ недоступен для редактирования, но она сможет читать его до тех пор, пока блокировка не будет снята.

Так что же произойдет, когда Боб получит блокировку, возможно, сохранит документ один или два раза, но затем выйдет из приложения, оставив блокировку висеть?

Как вы сами сказали, требование, чтобы клиент с блокировкой отправлял пинги с определенной частотой, вероятно, является лучшим вариантом.Если вы не получаете пинг от клиента в течение определенного периода времени, это фактически означает, что его клиент больше не отвечает.Если это веб-приложение, вы можете использовать JavaScript для проверки связи.Документ, который был сохранен последним, снимает блокировку, и теперь Кейт может получить его.

Пинг может содержать имя документа, который заблокирован клиентом, и сервер может рассчитать, когда был получен последний пинг для этого документа.

Другие советы

Первый вариант, который вы описываете, по сути, представляет собой пессимистическую модель блокировки, а второй — оптимистическую модель.Какой из них выбрать, на самом деле зависит от ряда факторов, но, по сути, от того, как бизнес хочет работать.Например, будет ли это причинять пользователям неоправданные неудобства, если документ, который им нужно редактировать, будет заблокирован другим пользователем?Что произойдет, если документ заблокирован, а кто-то уедет в отпуск с подключенным клиентом?Каковы вероятные разногласия по каждому документу, т.е.Насколько вероятно, что один и тот же документ будет изменен двумя пользователями одновременно? Насколько локализованы изменения в одном документе?(Если один и тот же раздел изменяется регулярно, выполнение слияния может занять больше времени, чем простое повторное внесение изменений).

Предполагая, что конфликты относительно невелики и/или размер каждого изменения довольно мал, я бы, вероятно, выбрал оптимистическую модель, которая разрешает конфликты с использованием автоматического или ручного слияния.Номер версии или контрольная сумма содержимого документа могут использоваться для определения необходимости слияния.

В настоящее время документы публикует ограниченный круг людей, каждый из которых работает над отдельной темой.Таким образом, неудобства, доставляемые замками, сводятся к минимуму.Люди в основном дополняют существующие документы и исправляют в них ошибки.

Говоря о пессимистической модели, сценария «клиент, оставленный подключенным на N дней», можно избежать, установив дату истечения срока блокировки, скажем, за один день до даты начала блокировки.Поскольку редактируемые документы ни в коем случае не являются критически важными и довольно редко изменяются несколькими пользователями, этого может быть достаточно.

Теперь рассмотрим оптимистическую модель.Как выявить различия, если документы имеют некую регулярную (скажем, иерархическую) структуру?Если не?Каковы шансы на успешное автоматическое слияние в этих случаях?

Ситуация усложняется, поскольку некоторые документы (редактируемые группой пользователей «Администраторы») содержат важную конфигурационную информацию (глобальный индекс документа, роли пользователей и т. д.).На мой взгляд, замки более выгодны именно для такого рода информации, поскольку она не меняется каждый день.Поэтому какое-то гибридное решение может быть приемлемым.

Что вы думаете?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top