Это функциональный алгоритм синхронизации?
Я работаю над базовым алгоритмом синхронизации для заметок пользователя. Я понял большую часть этого, но прежде чем я начну программировать его, я хочу запустить его здесь, чтобы увидеть, имеет ли это смысл. Обычно я заканчиваю тем, что не осознаю одну важную вещь, которую кто-то другой легко видит, чего я не могу. Вот как это работает:
У меня есть таблица в моей базе данных, куда я вставляю объекты с именем SyncOperation
, SyncOperation
это своего рода метаданные о характере того, что каждое устройство должно выполнять, чтобы быть в курсе. Скажем, у пользователя есть 2 зарегистрированных устройства, firstDevice
а также secondDevice
, firstDevice
создает новую заметку и отправляет ее на сервер. Теперь SyncOperation
создается с помощью идентификатора заметки, типа операции и processedDeviceList
, Я создаю SyncOperation
с типом "NewNot
е ", и я добавляю к этому исходный идентификатор устройства SyncOperation
"s processedDeviceList
, А сейчас secondDevice
регистрируется на сервере, чтобы узнать, нужно ли ему вносить какие-либо обновления. Это делает запрос, чтобы получить все SyncOperations
где secondDeviceId нет в processedDeviceList
, Он узнает, что его тип NewNote
, поэтому он получает новую заметку и добавляет себя в processedDeviceList
, Теперь это устройство синхронизировано.
Когда я удаляю заметку, я нахожу уже созданную SyncOperation
в таблице с типом "NewNote". Я меняю тип на Удалить, удаляю все устройства из processedDevicesList
кроме устройства, которое удалило заметку. Так что теперь, когда новые устройства вызывают, чтобы увидеть, что им нужно обновить, так как их deviceId не находится в processedList
им придется обработать это SyncOperation
, который говорит их устройству удалить эту соответствующую заметку.
И это обычно, как это будет работать. Мое решение слишком сложное? Можно ли это упростить? Кто-нибудь может вспомнить ситуацию, когда это не сработает? Будет ли это неэффективно в больших масштабах?
3 ответа
Звучит очень сложно - центральная база данных не должна отвечать за определение того, какие устройства получили какие обновления. Вот как я это сделаю:
- База данных содержит таблицу
SyncOperations
за каждое изменение. каждыйSyncOperation
это имеетchange_id
пронумерованы в порядке возрастания (то естьchange_id INTEGER PRIMARY KEY AUTOINCREMENT
.) - Каждое устройство хранит
current_change_id
число, представляющее, какое изменение он видел в последний раз. - Когда устройство хочет обновить, оно делает
SELECT * FROM SyncOperations WHERE change_id > current_change_id
, Это дает ему список всех изменений, которые должны быть актуальными. Применяйте каждый из них в хронологическом порядке.
Это имеет очаровательную особенность, что, если вы хотите, вы можете инициализировать новое устройство, просто создав новый клиент с current_change_id = 0
, Тогда это будет тянуть во всех обновлениях.
Обратите внимание, что это не сработает, если два пользователя могут выполнять одновременные правки (которые редактируют "выигрывает"?). Вы можете попытаться объединить изменения автоматически, или вы можете подать уведомление пользователю. Если вы хотите вдохновения, посмотрите на работу git
Система контроля версий (или Mercurial, или CVS...) для противоречивых правок.
Возможно, вы захотите взглянуть на SyncML, чтобы узнать, как обрабатывать операции синхронизации (http://www.openmobilealliance.org/tech/affiliates/syncml/syncml_sync_protocol_v11_20020215.pdf). SyncML существует уже некоторое время, и в качестве общедоступного стандарта он подвергся тщательному анализу и проверке. Существуют также реализации с открытым исходным кодом (на ум приходит Funambol), которые также могут предоставить некоторые подсказки кодирования. Вам не нужно использовать всю спецификацию, но ее чтение может дать вам несколько "ахах" моментов о синхронизации данных - я знаю, что это помогло продумать, что нужно сделать.
отметка
PS Более поздняя версия протокола - http://www.openmobilealliance.org/technical/release_program/docs/DS/V1_2_1-20070810-A/OMA-TS-DS_Protocol-V1_2_1-20070810-A.pdf
Я видел основную идею отслеживания операций в базе данных в другом месте, поэтому я осмелюсь сказать, что это может быть сделано для работы. Вы можете подумать о том, что должно произойти, если разные устройства используются в одно и то же время, и в конечном итоге представить противоречивые изменения - например, две разные попытки отредактировать одну и ту же заметку. Это может выглядеть как изменение пользовательского интерфейса, чтобы позволить им вмешаться, чтобы разрешить такие конфликты вручную.