2010-08-20 4 views
5

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

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

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

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

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

ответ

6

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

2

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

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

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

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

+0

Это отличный ответ, но на самом деле это не то, что я ищу: совместная часть редактирования действительно незначительна для части совместного использования, извините, если я не сделал это ясно. Принятие этого решения сделает вещи даже более сложными - слишком сложными для простого приложения для обмена текстовыми/кодовыми разделами. Количество случаев, которые мне нужно было бы рассмотреть, было бы ... совершенно невозможным с учетом сложности пользовательских взаимодействий. Тем не менее, отличный ответ, и дал мне что-то, чтобы размышлять, пока я жду следующего ответа ... –

0

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

У вас есть одна таблица с названием «active_edits» или что-то в этом роде со столбцом для document_id, пользователя и last_update_time. Допустим, ваше время ping составляет 1 минуту, а ваш тайм-аут - 5 минут. Таким образом, прецедент будет выглядеть так:

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

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

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

EDIT: Кроме того, я бы посмотрел window.onbeforeunload, а не onunload. Я считаю, что он выполняется раньше. Я считаю, что это веб-сайт функции (включен в slashdot), чтобы вы могли подтвердить, что вы действительно хотите покинуть страницу. Я думаю, что он работает в основных браузерах, кроме Opera.

0

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

Смежные вопросы