Architektura warstwy danych, która wykorzystuje zarówno localStorage, jak i serwer zdalny REST

Ktoś ma jakieś pomysły lub odniesienia, jak zaimplementować warstwę trwałości danych, która używa zarówno localStorage, jak i rest remote storage:

Dane pewnego klienta są przechowywane za pomocą localStorage (przy użyciu adaptera Ember-data indexedDB). Lokalnie przechowywane dane są synchronizowane ze zdalnym serwerem (za pomocą Ember-data RESTadapter).

Serwer zbiera wszystkie dane od klientów. Używając zbiorów matematycznych zapis:

Server = Client1 ∪ Client2 ∪ ... ∪ ClientN 

Gdzie ogólnie każdy zapis może nie być unikalnym dla pewnego klienta:

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

Oto kilka scenariuszy:

  • Klient tworzy rekord. Identyfikator rekordu nie może być ustawiony na kliencie, ponieważ może być w konflikcie z rekordem przechowywanym na serwerze. Dlatego nowo utworzony rekord musi zostać przekazany do serwera - > odbierz id - > Utwórz rekord w localStorage.

  • Rekord jest aktualizowany na serwerze, a w konsekwencji dane w localStorage i na serwerze tracą synchronizację. Tylko serwer to wie, więc Architektura musi zaimplementować architekturę push (?)

Czy używasz 2 sklepów (jeden dla localStorage, jeden dla REST) i synchronizujesz je między nimi, czy używasz hybrydowego adaptera indexedDB/REST i piszesz kod synchronizacji wewnątrz adaptera?

Czy widzisz jakiś sposób na uniknięcie implementacji push (Web Sockets, ...)?

Author: Panagiotis Panagi, 2012-11-27

1 answers

Na poruszany problem nie można odpowiedzieć w kilku akapitach lub odpowiedzieć po prostu. Niemniej jednak, oto moja próba...

Po pierwsze, istnieje wiele trudności z podejściem, które przyjąłeś:

  1. klienci muszą być zawsze podłączeni do sieci, aby tworzyć Dane i odbierać klucze z serwera.
  2. Jeśli tworzysz różne sklepy (localstorage & REST), cały kod aplikacji wymagający danych musi wyglądać w obu sklepach. To znacznie zwiększa złożoność każdej części aplikacji.
  3. Po utworzeniu wiersza, jeśli chcesz utworzyć wiersze potomne, musisz poczekać, aż serwer zwróci klucz podstawowy, zanim będziesz mógł odwołać się do niego jako klucz obcy w wierszu potomnym. W przypadku umiarkowanie złożonych struktur danych staje się to dużym obciążeniem.
  4. gdy serwer przestaje działać, wszyscy klienci nie mogą tworzyć danych.

Oto moje podejście. Używa SequelSphereDB, ale większość pojęć może być ponownie wykorzystana w innych systemy zarządzania danymi klienta.

Po pierwsze: użyj uuid dla kluczy podstawowych.

Większość systemów zarządzania danymi klientów powinna zapewniać sposób generowania uniwersalnie unikalnych identyfikatorów. SequelSphere robi to po prostu za pomocą funkcji SQL: UUID (). Posiadanie UUID jako klucza podstawowego dla każdego wiersza pozwala na generowanie kluczy podstawowych na dowolnym kliencie w dowolnym momencie bez konieczności kontaktowania się z serwerem i nadal gwarantuje, że identyfikatory będą unikalne. To również w konsekwencji pozwala na aplikacja do pracy w trybie" offline", niewymagająca połączenia z serwerem w czasie pracy. To również powstrzymuje powalony Serwer od sprowadzenia wszystkich klientów w dół.

Po drugie: użyj jednego zestawu tabel, które odzwierciedlają serwery.

Jest to bardziej wymóg prostoty niż cokolwiek innego. Jest to również wymóg dla dwóch kolejnych podstawowych zasad.

Po trzecie: do synchronizacji w dół małych zbiorów danych, całkowicie odświeżające preferowane są dane Klienta z serwera.

Jeśli to możliwe, wykonaj pełne odświeżenie danych na kliencie z serwera. Jest to prostszy paradygmat i skutkuje mniej wewnętrznymi kwestiami integralności danych. Podstawową wadą jest wielkość danych w transferze.

Po czwarte: do synchronizacji w dół dużych zbiorów danych, wykonaj aktualizacje "transakcyjne"

Tutaj Moje podejście staje się nieco bardziej złożone. Jeśli zbiory danych są zbyt duże i wymagają tylko zmienione wiersze, aby zostać zsynchronizowane, musisz znaleźć sposób na zsynchronizowanie ich zgodnie z"transakcjami". Oznacza to, że wstawia / aktualizuje/usuwa w kolejności, w jakiej zostały wykonane na serwerze, aby zapewnić prosty skrypt do wykonywania tego samego na kliencie.

Lepiej jest mieć tabelę na serwerze rejestrującą transakcje, które mają być zsynchronizowane z urządzeniem. Jeżeli nie jest to możliwe, wtedy zamówienie może być często rejestrowane na serwerze przy użyciu znaczników czasu w wierszach i mając klienta poproś o wszystkie zmiany od określonego znacznika czasu. Duży minus: będziesz musiał śledzić usunięte wiersze albo przez" logiczne " usunięcie, albo śledząc je we własnej tabeli. Mimo to, izolowanie złożoności od serwera jest lepsze niż rozprzestrzenianie jej na wszystkich klientów.

Po piąte: do synchronizacji w górę, Użyj aktualizacji "transakcyjnych"

TutajSequelSphereDB naprawdę błyszczy: będzie śledzić dla ciebie wszystkie wstawki, aktualizacje, i usuwa wykonywane z tabelami, a następnie przekazuje je z powrotem w czasie synchronizacji. Robi to nawet po ponownym uruchomieniu przeglądarki, ponieważ utrzymuje informacje w localstorage / indexeddb. Nawet odpowiednio obsługuje commity i rollbacki. Aplikacja kliencka może wchodzić w interakcje z danymi tak, jak zwykle, bez konieczności myślenia o nagrywaniu zmian, a następnie używać "śledzenia zmian" SequelSphereDB, aby odtworzyć zmiany w czasie synchronizacji.

Jeśli nie używasz SequelSphere (powinieneś być), a następnie zachowaj osobną tabelę na kliencie, aby rejestrować wszystkie wstawiania, aktualizacje i usuwanie, które wykonuje klient. Za każdym razem, gdy aplikacja kliencka wstawia/aktualizuje / usuwa wiersze, zrób kopię tego w tabeli "transakcja". / Align = "left" / Na serwerze po prostu wykonaj te same kroki w tej samej kolejności, aby odtworzyć dane, które były na kliencie.

Również ważne: zawsze wykonaj synchronizację w górę przed pełnym odświeżeniem tabel klienta z serwera. :)

Wniosek

Proponuję postawić na prostotę ponad złożoność w jak największej liczbie miejsc. Używanie uuid dla kluczy podstawowych jest niezwykle pomocne w tym celu. Korzystanie z jakiegoś rodzaju "śledzenia zmian" jest również bardzo przydatne. Korzystanie z narzędzia takiego jak SequelSphereDB do śledzenia zmian jest najbardziej pomocne, ale nie jest konieczne w tym podejściu.

Pełne ujawnienie: jestem blisko związany z firmą SequelSphere, ale ten produkt naprawdę nie jest niezbędne do wdrożenia powyższego podejścia.

 7
Author: John Fowler,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-29 23:03:02