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, ...)?
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ś:
- klienci muszą być zawsze podłączeni do sieci, aby tworzyć Dane i odbierać klucze z serwera.
- 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.
- 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.
- 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.
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