Архитектура для слоя данных, использующего localStorage и удаленный сервер REST

у кого - нибудь есть идеи или ссылки о том, как реализовать слой сохраняемости данных, который использует как локальный хранилище, так и удаленное хранилище REST:

данные определенного клиента хранятся в localStorage (используя адаптер Ember-data indexedDB). Локально сохраненные данные синхронизируются с удаленным сервером (с помощью Ember-data RESTadapter).

сервер собирает все данные от клиентов. Используя математические наборы Примечание:

Server = Client1 ∪ Client2 ∪ ... ∪ ClientN 

где, в общем, любая запись не может быть уникальной для определенного клиента:

ClientX ∩ ClientY ≠ 0,  ∀ X,Y ∈ [1,N]

вот несколько сценариев:

  • клиент создает запись. Идентификатор записи не может быть установлен на клиенте, так как он может конфликтовать с записью, хранящейся на сервере. Поэтому вновь созданная запись должна быть зафиксирована на сервере - > получить идентификатор - > создать запись в localStorage.

  • запись обновляется на сервере, и как следствие данные в localStorage и на сервере выходят из синхронизации. Только сервер знает это, поэтому архитектура должна реализовать архитектуру push (?)

будете ли вы использовать 2 магазина (один для localStorage, один для REST) и синхронизировать между ними или использовать гибридный адаптер indexedDB/REST и писать код синхронизации внутри адаптера?

можете ли вы увидеть какой-либо способ избежать реализации push (Web Sockets, ...)?

1 ответов


на проблему, которую вы поднимаете, нельзя ответить в нескольких абзацах или ответить просто. Тем не менее, вот моя попытка...

во-первых, есть ряд трудностей с подходом у вас принято:

  1. клиенты всегда должны быть подключены к сети для создания данных и получения ключей от сервера.
  2. если вы делаете разные магазины (localstorage & REST), весь код приложения, требующий данных, должен выглядеть в обоих магазинах. Что существенно увеличивает сложность каждой части приложения.
  3. после создания строки, Если вы хотите создать дочерние строки, вы должны подождать, пока сервер вернет первичный ключ, прежде чем ссылаться на него как на внешний ключ в дочерней строке. Для любых умеренно сложных структур данных это становится тяжелым бременем.
  4. когда сервер выходит из строя, все клиенты не могут создавать данные.

вот мой подход. Он использует SequelSphereDB, но большинство концепции могут быть повторно использованы в других клиентских системах управления данными.

FIRST: используйте UUIDs для первичных ключей.

большинство клиентских систем управления данными должны обеспечивать способ генерации универсально уникальных идентификаторов. SequelSphere делает это просто с помощью функции SQL: UUID (). Наличие UUID в качестве первичного ключа для каждой строки позволяет создавать первичные ключи на любом клиенте в любое время без необходимости связываться с сервером и гарантировать, что Идентификаторы будут уникальными. Это, следовательно, позволяет приложению работать в "автономном" режиме, не требуя подключения к серверу во время выполнения. Это также удерживает сбитый сервер от приведения всех клиентов вниз.

SECOND: используйте один набор таблиц, которые отражают сервер.

Это больше требование для простоты, Чем что-либо еще. Это также требование для следующих двух основных принципы.

третье: для нисходящей синхронизации небольших наборов данных предпочтительно полное обновление клиентских данных с сервера.

по возможности выполните полное обновление данных на клиенте с сервера. Это более простая парадигма и приводит к меньшим внутренним проблемам целостности данных. Основным недостатком является размер данных при передаче.

четвертое: для нисходящей синхронизации больших наборов данных выполните 'Транзакционные' обновления

здесь мой подход становится немного более сложным. Если наборы данных слишком велики и требуют синхронизации только измененных строк, вы должны найти способ синхронизировать их в соответствии с "транзакциями". То есть: вставки/обновления/удаления в том порядке, в котором они были выполнены на сервере, чтобы обеспечить простой скрипт для выполнения на клиентском.

предпочтительно иметь таблицу на сервере, записывающую транзакции на будьте синхронизированы с устройством. Если это невозможно, то заказ часто может быть записан на сервере с использованием временных меток в строках, и клиент запрашивает все изменения с определенной временной метки. Большой минус: вам нужно будет отслеживать удаленные строки либо "логическими" удалениями, либо отслеживая их в своей собственной таблице. Тем не менее, изоляция сложности к серверу предпочтительнее, чем распространение ее по всем клиентам.

в-пятых: для upward-синхронизация, используйте "транзакционные" обновления

вот тут SequelSphereDB действительно сияет: Он будет отслеживать для вас все операции вставки, обновления и удаления, выполненные по таблицам, а затем предоставить их вам на время синхронизации. Он даже делает это через перезапуск браузера, так как он сохраняет информацию в localstorage/indexeddb. Он даже обрабатывает коммиты и откаты соответствующим образом. Клиентское приложение может взаимодействовать с данными, как обычно было бы без необходимости думать о записи изменений, а затем использовать SequelSphereDB "изменить трекеры" для воспроизведения изменений во время синхронизации.

Если вы не используете SequelSphere (вы должны быть), затем сохраните отдельную таблицу на клиенте для записи всех вставок, обновлений и удалений, выполняемых клиентом. Всякий раз, когда клиентское приложение вставляет/обновляет/удаляет строки, сделайте копию этого в таблице "транзакция". Во время восходящей синхронизации отправьте их. На сервер просто выполняет те же шаги в том же порядке, чтобы реплицировать данные, которые были на клиенте.

также важно: всегда выполняйте восходящую синхронизацию перед полным обновлением клиентских таблиц с сервера. :)

вывод

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

полное раскрытие информации: я тесно связан с компанией SequelSphere, но этот продукт действительно не нужен для реализации вышеуказанного подхода.