logo
logo
Некоторые соображения [Дим(м) 24/04/2013 16:15]
Думаю, одними логами всё же не обойтись - сама база целиком тоже должна быть в облаке. Например, для сценария "запустил программу на новом устройстве".
 
Что касается использования логов для синхронизации, это, мне кажется, весьма широко используемая практика.
Возьмите те же (распределённые) системы контроля версий, например, журналируемые файловые системы или кластеры баз данных.
 
Каждую запись в такой лог можно дополнительно снабжать разнообразной мета-информацией. Например, о том, кто автор этого изменения, когда оно было внесено, на основании какой версии базы было сделано.
 
К сожалению, никакого практического опыта реализации подобных систем у меня нету. Так что с технической стороны я мало что смогу посоветовать.
 
Что касается вопросов
(а) конфликт, по сути, будет только в том случае, если изменения затрагивают одну и ту же запись и при этом не идентичны
 
решение в таком случае только одно - спросить у пользователя
все так делают: Windows при копировании, если файл уже существует, системы контроля версий предлагают откорректировать результат merge с помощью 3-way diff, разнообразные редакторы, если редактируемый файл был кем-то изменён на диске
 
думаю, будет вполне нормально, если AC будет показывать сообщение с конфликтными изменениями и спрашивать пользователя, каким должен быть итог
 
при этом, конечно, количество конфликтных ситуаций нужно минимизировать
например, было бы крайне неудобно считать конфликтом создание двух разных записей с одинаковым внутренним id
 
(б) изменения должны отправляться на сервер "поштучно" (это, кстати, позволит и синхронизацию сделать более real time)
тогда всё, что пришло на сервер, идёт "в работу" без каких-либо непоняток
с клиентской стороны тоже нужно хранить аналогичный лог "своих" изменений и удалять из него записи, когда от сервера пришло подтверждение получения
тогда после восстановления соединения клиент просто дошлёт изменения, которые не удалось доставить в прошлый раз
 
как вариант, могу попробовать предложить такую схему:
- в базе создаются триггеры на модификацию всех синхронизируемых таблиц и для каждого изменения в специальную таблицу сохраняется, что, где и как изменилось (например, в виде соответствующего SQL-запроса: "INSERT TO transactions (...) VALUES (...)")
(в общем-то, с помощью аналогичного подхода обычно делают UNDO - Undo/Redo in SQLite)
 
- специальный поток, ответственный за синхронизацию, периодически читает данные из этой таблицы и отправляет их на сервер
- когда сервер подтверждает получение, запись из таблицы удаляется
 
- на сервере каждой записи в логе присваивается уникальный инкрементальный номер или метка времени (см. также HTTP ETag)
- вместе с записью из лога клиенту всегда отправляется и эта метка
 
- ещё один поток на клиенте периодически опрашивает сервер: "были ли какие-то не мои изменения после метки Х?"
- и когда от сервера приходит какое-то обновление, применяет его к локальной базе без занесения в локальный лог изменений
- и запоминает у себя "последнюю успешную метку" для использования в следующем запросе
 
остаётся открытым вопрос удаления старых записей из лога на сервере
но сервер, по сути, знает всех своих клиентов "в лицо" и может хранить "последнюю использованную метку" для каждого из них
соответственно, записи в логе, более старые, чем самая старая метка клиентов, можно безболезненно удалять
 
м-м-м..
я вот только сейчас подумал, что этот сценарий требует использование "активного сервера"
а вы же, наверное, хотели бы использовать сервер только в качестве "разделяемого хранилища"...
(отсюда, кстати, вытекает и отличие в подходе ActiveSync - когда нету сервера-арбитра, нужна база целиком (?), чтобы самостоятельно провести анализ)
 
... но если присмотреться, то сервер тут всё же может быть "почти пассивным"
всё, что от него требуется - INSERT с auto_increment для колонки с меткой и SELECT с парой условий (чистку логов пока оставляем за рамками)
т.е. вполне подойдёт обычная БД
но с Dropbox, например, это всё равно не прокатит, да и в случае p2p придётся придумывать что-то другое..