Мониторинг пользовательских сессий для предотвращения редактирования конфликта - PullRequest
5 голосов
/ 20 августа 2010

Я работаю над чем-то похожим на pastebin (да, это , что generic), но допускает многопользовательское редактирование.Очевидная проблема заключается в том, что несколько пользователей пытаются редактировать один и тот же файл.Я думаю о том, как заблокировать файл, когда над ним работает один пользователь (это не лучшее решение, но мне не нужно ничего слишком сложного), но для предотвращения / предупреждения пользователя мне, очевидно, понадобитсясистема контроля за сессиями редактирования каждого пользователя.Работая с базой данных и ajax, я подумываю о двух решениях.

Первое - это когда страница редактирования пингует сервер через произвольный интервал, скажем минуту, и она обновляет запись сеанса редактирования вдБ.Затем в следующий раз, когда запрос скрипта на редактирование, он проверяет самый последний пинг, и, если самым последним был другой произвольный период времени, скажем, пять минут, то мы предполагаем, что предыдущий пользователь завершил работу, и файл можно снова отредактировать.Конечно, проблема этого метода заключается в том, что предположение о том, что предыдущий пользователь вышел из системы, является просто предположением.У него могло быть слабое соединение Wi-Fi, и он просто пропадал в течение десяти минут, все время с открытым окном.

Конечно, чтобы решить эту проблему, мы бынеобходимо, чтобы сервер отвечал на новый запрос от ранее закрытых сеансов с ошибкой, сообщая клиентской стороне указать пользователю, что его сеанс завершился, и затем обработал его, скажем, сохранив его как другой файл на сервереи попросить пользователя объединить его вручную и т. д. Само собой разумеется, что это довольно ужасно для конечного пользователя.

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

Есть ли у кого-нибудь другое, более изящное решение этой проблемы?

Ответы [ 4 ]

6 голосов
/ 31 августа 2010

Если вы ожидаете, что число одновременных правок файла будет незначительным, вы можете просто сохранить номер версии файла в БД, и когда пользователь загружает файл в свой браузер, он также получает номер версии.Они могут загружать свои изменения только в случае совпадения номера версии.Первый загрузит выигрыш.При обнаружении конфликта вы должны отправить обратно самый последний файл и изменения пользователя, чтобы пользователь мог вручную внести изменения.Преимущество в том, что это работает, даже если один и тот же пользователь делает два одновременных редактирования.Если эта функция часто используется, вы можете добавить слияние на стороне клиента, аналогичное тому, которое использует инструмент сравнения (но в этом случае вам может понадобиться сохранить старые ревизии).

2 голосов
/ 22 августа 2010

Вам, вероятно, лучше пойти на решение "слияния".Используя этот подход, вам нужно проверять изменения, только когда пользователь публикует свой документ на сервере.

Основной подход будет следующим: 1. Пользователь A получает документ для редактирования, документ версии 1 2. ПользовательB получает документ для редактирования, документ имеет версию 1 3. Пользователь B публикует некоторые изменения, включая номер базовой версии 1 4. Сервер обновляет документ, документ теперь имеет версию 2 5. Пользователь B публикует некоторые изменения, включая базовую версиючисло 1 6. Сервер отвечает, что документ изменился с тех пор, как пользователь начинает редактирование, и отправляет пользователю новый документ и его версию - пользователю затем нужно будет выполнить любое объединение своих изменений в версии документа 2 и отправить обратно на сервер.,По сути, пользователь сейчас редактирует документ версии 2 7. Пользователь A публикует некоторые изменения, в том числе номер версии 2. 8. Сервер обновляет документ, который теперь имеет версию 3

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

Основным преимуществом этого подхода является то, что пользователи никогда не блокируют файлы, поэтому вам не нужны произвольные «тайм-ауты».

0 голосов
/ 31 августа 2010

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

0 голосов
/ 27 августа 2010

Я бы сказал, что вы на правильном пути.Я бы, вероятно, реализовал гибридное решение:

Имею одну таблицу с именем "active_edits" или что-то подобное со столбцом для document_id, user и last_update_time.Допустим, ваше время пинга составляет 1 минуту, а время ожидания - 5 минут.Поэтому сценарий использования будет выглядеть следующим образом:

Боб открывает документ.Проверяет last_update_time.Если это более 5 минут назад, обновите таблицу с Бобом и текущим временем.Если это не так, над документом работает кто-то другой, поэтому выведите сообщение об ошибке.Предполагая, что он не редактируется, Боб некоторое время работает над документом, и клиент пингует время обновления каждую минуту.

Я бы сказал, do включает кнопку «Закончить редактирование» иобработчик onunload.Что касается загрузки, то, насколько я понимаю, может быть ненадежным, но может также добавить его.Оба из них будут отправлять на сервер одно сообщение только для отправки о том, что Боб готов.Даже если Боб не нажмет «Закончить редактирование» и выгрузится из-под загрузки, в худшем случае другому пользователю придется подождать еще 5 минут для редактирования.Преимущество состоит в том, что если они обычно работают (справедливое предположение), то система работает немного лучше.

В случае, когда вы описали, где Боб находится в плохом беспроводном соединении или делает перерыв: я бы сказал, что этоне имеет большого значения.Ваша функция ping должна убедиться, что документ не был передан кому-либо еще со времени последнего пинга Боба.Если это так, просто дайте Бобу сообщение «кто-то еще начал работать над документом» и дайте им возможность перезагрузить.

РЕДАКТИРОВАТЬ: Кроме того, я бы посмотрел в window.onbeforeunload , не загружается.Я считаю, что это выполняется раньше.Я полагаю, что это функция веб-сайта (включая slashdot), позволяющая подтвердить, что вы действительно хотите покинуть страницу.Я думаю, что это работает в основных браузерах, кроме Opera.

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