Как запретить одновременное редактирование одного документа несколькими людьми?
Товарищи, есть такая проблема. Допустим, существует редактор документа (текстовый, визуальный, неважно). Редактор раз в 20 секунд сохраняет то, что у него есть в черновик.
На сайте есть авторизация. Доступ одновременно с разных машин на один аккаунт возможен. Авторизация на сайте не означает то, что человек будет находиться в редакторе документа.
Как определить, что документ уже редактируется одним человеком, чтобы второй, случайно открыв тот же документ, не имел возможности его редактировать и не срабатывало автосохранение? А то черновик перетирается одним, потом другим и получается каша.
Я понимаю, что у гугла круто сделано, но там хитрые сервера, совместный доступ и все остальное.
В рамках одного бразуера проблема решаема (если 2 вкладки открыты, к примеру), даже через JS. А вот с разных машин - уже проблема.
Спасибо.
Это называется словом lock.
Пользователь открыл для редактирования документ - поставили метку locked с user_id и временем доступа.
Другой пользователь потом заходит, видит лок и открыть для записи уже не может.
Можно реализовать множество всяких стратегий по работе с локами, как вам удобно. Можно к примеру дать право насильственно тоже открыть для записи, вопреки локу.
И тогда если этот "вторженец" первым успел сохранить документ - ему меньше головной боли, чем тому, кто позже станет сохранять редактирование.
Конфликт такой проще всего решить через уведомление пользователя о том, что запись уже изменилась другим человеком и показать актуальную версию с датой сохранения в какой-то отдельной форме, не затирая текущую правку.
А можно вообще запретить редактирование, когда висит лок и только администратор сможет его снять, если он висит аномально долго.
Это вариант. Мы сейчас пробуем прикрутить pusher, ибо в сервисе он уже используется и менять контент на лету для юзера с соответствующей пометкой. Просто хочется выслушать мнение сообщества.
Сделали в итоге через нотификации, используя Pusher. В нем и передаем данные о том, что сейчас редактируется, и у юзера фактически появляется на руках рабочая версия документа. Этого вполне достаточно для текущей задачи. Изобретать велосипед не стали. В принципе, у сервиса, аналогичного нашему - такая система. Спасибо.
Хорошо. Я редактирую документ, а потом мне пришло в голову выдернуть шнур из розетки. Статус повиснет, пока я его не разблокирую вручную. Опять же выводить окно, что я согласен, что я буду редактировать его и остальных редакторов слать лесом - одно из вариантов решений. Но какой-то не такой вариант :)
@DaFive очень просто. Ajax-ом отправляйте через какой-то промежуток времени(напр. 10с) на сервер сообщение, обнуляющее счетчик времени. Если счетчик дошел до таймаута(напр, 60с), снимать блокировку с документа.
@samoilenkoevgeniy где я прошу придумать решение? Я прошу поделиться мыслями, может кто уже так делал. А решение уже на стадии завершения, и @akubintsev подтвердил догадки о решении конфликта через нотификации. Сделали мы их через pusher.
Хранить поле ревизии. При открытии редактора в скрытом поле сохраняется идентификатор последней ревизии, при сохранении сравнивается, если идентификатор изменился, значит документ изменен. Ну и дальше уже думать что делать, либо разницу показывать, либо еще чего. Примерно так поступает redmine.