Сервер документов: обработка одновременных сохранений - PullRequest
2 голосов
/ 13 августа 2008

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

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

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

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

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

Ответы [ 3 ]

1 голос
/ 13 августа 2008

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

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

0 голосов
/ 13 августа 2008

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

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

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

Ситуация усложняется, поскольку некоторые документы (отредактированные группой пользователей 'admins') содержат важную информацию о конфигурации (глобальный индекс документа, роли пользователя и т. Д.). На мой взгляд, блокировки более полезны именно для такого рода информации, потому что они не меняются каждый день. Так что какое-то гибридное решение может быть приемлемым.

Что ты думаешь?

0 голосов
/ 13 августа 2008

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...