8

Piszę prosty „Todo - helloworld” z jqueryMobile nokaut + + + wietrze WebAPI poznać OSO (Single Page Application) w kontekście telefonii komórkowej (zawodne połączenia internetowego)Czy istnieją najlepsze praktyki/wzorce do synchronizowania danych lokalnych i zdalnych w SPA (aplikacje pojedynczej strony html5)?

Aby umożliwić wykorzystanie webapp nieaktywny wykorzysta

  • Application Cache
  • localStorage

App powinny stosować w miarę możliwości zdalnej bazy danych dla załadunku i zapisywanie da ta, ale powinna być w stanie płynnie przełączyć się na localstorage w trybie offline i zsynchronizować zmiany lokalne/zdalne po powrocie do trybu online.

Wracając do pytania: App użyje Breeze za EntityManager do zarządzania danymi (lokalnej pamięci podręcznej i zdalnego Sync)

  • "remoteDb"

Aby złagodzić niespójności problemów/współbieżności bym użyj 2 kluczy localstorage:

  • "localDb" dla lokalnej kopii zdalnej bazy danych (lista todos)
  • „localPendingChanges” dla zmian App nie był w stanie złożyć do zdalnej bazy danych

więc przepływ będzie bardziej lub mniej Be (pseudokod):

LoadData 
    if(online) 
    load remoteDb 
    save localDb     // save a local copy of the fresh loaded remotDb 
    if(localPendingChanges) 
     load localPendingChanges  // we are merging in the Breeze entityManager remote data with localPendingChanges 
     Savedata      // we are online and we have pending changes, so we should sync everything back to the remoteDb as soon as possible 
    if(offline) 
    load localDb 
    if(localPendingChanges) 
     load localPendingChanges  // we are merging in the Breeze entityManager local data with localPendingChanges 

SaveData 
    if(online) 
    save remoteDb 
    clear localPendingChanges  // until we are online there is no need to keep localPendingChanges 
    LoadData      // we are loading data from remoteDb to update our localDb to the latest version 
    if(offline) 
    save localPendingChanges  // we are saving only the changes to localstorage 

Co sądzisz na ten temat podejście? Czy to bałagan? Czy to jest w porządku? Co z problemami z współbieżnością w scenariuszu z wieloma użytkownikami?

+0

Szukam dobrego podejścia. Chociaż mam wrażenie, że jest jeden lepszy, jest to bardzo dobry. +1 – rpax

Odpowiedz

3

Wydaje się to uzasadnione, nie do końca pewne, dlaczego chcesz dwa klucze localStorage. Element entityState (niezmodyfikowany, zmodyfikowany, dodany, usunięty) każdej jednostki umieszczonej w localStorage jest utrzymywany, więc zawsze można "wyodrębnić" (patrz metoda EntityManager.getEntities) tylko oczekujące zmiany z dowolnej lokalnej kopii. Dlaczego więc nie po prostu zapisać cały stan entityManager do localStorage, zanim zamkniesz aplikację.

W przypadku problemów z współbieżnością zdecydowanie należy ustawić właściwość współbieżności w każdym obiekcie entityType. Tak długo, jak to istnieje, i jeśli oszczędzasz za pośrednictwem Entity Framework, breeze wykryje wszelkie optymistyczne naruszenia współbieżności podczas składowania i wyrzuci wyjątek. Oczywiście po takim wyjątku ustaliłeś właściwe zachowanie dla swojej aplikacji.

Jestem pewien, że już go widziałeś, ale QueryOptions.MergeStrategy (PreserveChanges, OverwriteChanges) może być bardzo pomocne w utrzymywaniu lub nadpisywaniu danych na lokalnym komputerze po jakimkolwiek zapytaniu.

+0

Widzę powód posiadania oddzielnego klucza (lub klucze) dla zmian. Jest to rozsądny sposób na izolowanie sandboxowych sesji edycyjnych, zwłaszcza jeśli możesz mieć kilka niezapisanych edycji piaskownicy i chcesz, aby każdy z nich był traktowany w oddzielnych transakcjach. Ma to również sens, jeśli zamierzasz przechowywać oczekujące zmiany lokalnie "w trakcie" w celu ochrony użytkownika przed utratą pracy z powodu wypadków lub t ombstoning. Te zmiany byłyby prawdopodobnie małe i krótkotrwałe; chcesz je wyizolować z większych, dłuższych niezmienionych danych. Jak widzisz, zależy to od jasnego zrozumienia potrzeb aplikacji. – Ward

+1

Dziękuję, Jay, używam EF, więc definitywnie podążę za twoją sugestią o właściwościach współbieżności (muszę trochę w to zaglądać, nigdy nie używałem EF aż do teraz :-)) – frenchfaso

+0

Zostanę z dwoma kluczami w localstorage, ponieważ, choć nie jest to konieczne (jak zauważyłeś), chciałbym zachować dwa oddzielne dla czytelności – frenchfaso

2

Myślę, że masz rację utrzymując lokalne zmiany w oddzielnym miejscu od tych, które są zsynchronizowane z serwerem. Zajmuję się tym problemem od kilku miesięcy i wymyśliłem coś, co bardzo przypomina system kontroli wersji, w którym wszystkie dane w kluczu w zestawie i wszystko jest oddzielnie. Możesz pobrać zmiany z serwera do lokalnej bazy danych i zajmie się tym, czy zostały one zmienione po obu stronach przez wywołanie zwrotne rozwiązywania konfliktów.

W tej chwili nie wiem zbyt wiele o Knockout, ale sama biblioteka nie jest zależna od żadnych oddzielnych projektów i przechodzi testy przypadków w Node.JS, Dojo i jQuery. Ma bardzo ciasny interfejs API (.get, .set, .feed (do ładowania pobranych danych z serwera) i .getFirst (w celu uzyskania dostępu do tego, co należy przesłać):

Adres URL to https://github.com/forbesmyester/SyncIt, ma dość obszerną wersję demonstracyjną i dokumenty również.

+0

Dobry projekt. +1 – rpax