Архитектура для слоя данных, использующего 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 ответов
на проблему, которую вы поднимаете, нельзя ответить в нескольких абзацах или ответить просто. Тем не менее, вот моя попытка...
во-первых, есть ряд трудностей с подходом у вас принято:
- клиенты всегда должны быть подключены к сети для создания данных и получения ключей от сервера.
- если вы делаете разные магазины (localstorage & REST), весь код приложения, требующий данных, должен выглядеть в обоих магазинах. Что существенно увеличивает сложность каждой части приложения.
- после создания строки, Если вы хотите создать дочерние строки, вы должны подождать, пока сервер вернет первичный ключ, прежде чем ссылаться на него как на внешний ключ в дочерней строке. Для любых умеренно сложных структур данных это становится тяжелым бременем.
- когда сервер выходит из строя, все клиенты не могут создавать данные.
вот мой подход. Он использует SequelSphereDB, но большинство концепции могут быть повторно использованы в других клиентских системах управления данными.
FIRST: используйте UUIDs для первичных ключей.
большинство клиентских систем управления данными должны обеспечивать способ генерации универсально уникальных идентификаторов. SequelSphere делает это просто с помощью функции SQL: UUID (). Наличие UUID в качестве первичного ключа для каждой строки позволяет создавать первичные ключи на любом клиенте в любое время без необходимости связываться с сервером и гарантировать, что Идентификаторы будут уникальными. Это, следовательно, позволяет приложению работать в "автономном" режиме, не требуя подключения к серверу во время выполнения. Это также удерживает сбитый сервер от приведения всех клиентов вниз.
SECOND: используйте один набор таблиц, которые отражают сервер.
Это больше требование для простоты, Чем что-либо еще. Это также требование для следующих двух основных принципы.
третье: для нисходящей синхронизации небольших наборов данных предпочтительно полное обновление клиентских данных с сервера.
по возможности выполните полное обновление данных на клиенте с сервера. Это более простая парадигма и приводит к меньшим внутренним проблемам целостности данных. Основным недостатком является размер данных при передаче.
четвертое: для нисходящей синхронизации больших наборов данных выполните 'Транзакционные' обновления
здесь мой подход становится немного более сложным. Если наборы данных слишком велики и требуют синхронизации только измененных строк, вы должны найти способ синхронизировать их в соответствии с "транзакциями". То есть: вставки/обновления/удаления в том порядке, в котором они были выполнены на сервере, чтобы обеспечить простой скрипт для выполнения на клиентском.
предпочтительно иметь таблицу на сервере, записывающую транзакции на будьте синхронизированы с устройством. Если это невозможно, то заказ часто может быть записан на сервере с использованием временных меток в строках, и клиент запрашивает все изменения с определенной временной метки. Большой минус: вам нужно будет отслеживать удаленные строки либо "логическими" удалениями, либо отслеживая их в своей собственной таблице. Тем не менее, изоляция сложности к серверу предпочтительнее, чем распространение ее по всем клиентам.
в-пятых: для upward-синхронизация, используйте "транзакционные" обновления
вот тут SequelSphereDB действительно сияет: Он будет отслеживать для вас все операции вставки, обновления и удаления, выполненные по таблицам, а затем предоставить их вам на время синхронизации. Он даже делает это через перезапуск браузера, так как он сохраняет информацию в localstorage/indexeddb. Он даже обрабатывает коммиты и откаты соответствующим образом. Клиентское приложение может взаимодействовать с данными, как обычно было бы без необходимости думать о записи изменений, а затем использовать SequelSphereDB "изменить трекеры" для воспроизведения изменений во время синхронизации.
Если вы не используете SequelSphere (вы должны быть), затем сохраните отдельную таблицу на клиенте для записи всех вставок, обновлений и удалений, выполняемых клиентом. Всякий раз, когда клиентское приложение вставляет/обновляет/удаляет строки, сделайте копию этого в таблице "транзакция". Во время восходящей синхронизации отправьте их. На сервер просто выполняет те же шаги в том же порядке, чтобы реплицировать данные, которые были на клиенте.
также важно: всегда выполняйте восходящую синхронизацию перед полным обновлением клиентских таблиц с сервера. :)
вывод
Я предлагаю идти для простоты над сложностью в как можно большем количестве мест. Использование UUIDs для первичных ключей чрезвычайно полезно для этого. Использование каких-то" трекеров изменений " также очень полезно. Использование такого инструмента, как SequelSphereDB для отслеживания изменений для вас наиболее полезно, но не обязательно для этого подхода.
полное раскрытие информации: я тесно связан с компанией SequelSphere, но этот продукт действительно не нужен для реализации вышеуказанного подхода.