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

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

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

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

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

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

13.08.2008 11:49:14
3 ОТВЕТА
РЕШЕНИЕ

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

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

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

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

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

0
13.08.2008 12:10:43

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

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

1
13.08.2008 13:26:57

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

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

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

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

Как вы думаете?

0
13.08.2008 14:07:32