Heim >Web-Frontend >js-Tutorial >Replicache Big Picture
Dies ist ein Framework, das bei der Implementierung von Local First Software hilft. Git hilft in ähnlicher Weise bei der Organisation synchronisierter Aufgaben durch Push und Pull.
Replicache synchronisiert Serverdaten asynchron hinter den Kulissen, wodurch Server-Roundtrips vermieden und sofortige Änderungen an der Benutzeroberfläche ermöglicht werden.
Replicache besteht aus mehreren Elementen.
Replicache kann als browserinterner Schlüsselwertspeicher betrachtet werden, der intern Git-ähnliche Vorgänge enthält. Zuerst in den Speicher schreiben und später synchronisieren.
Dies ist eine von uns erstellte Anwendung, ähnlich einer Webanwendung. Es ist die Entität, die den Zustand in Replicache speichert. Mutator und Abonnement werden implementiert, um den Status zu ändern und darauf zu reagieren
Ihr ServerDer Server muss Push (Upstream) und Pull (Downstream) implementieren, um mit dem Replicache des Clients zu kommunizieren.
Quelle
import {Replicache} from "replicache"; const rep = new Replicache({ name: userID, ... }); console.log(rep.clientID);Normalerweise gibt es einen Client pro Tap. Der Client ist volatil und folgt dem Lebenszyklus der Registerkarte. Hat eine eindeutige Client-ID.
Client-Gruppe ist eine Gruppe von Clients, die lokale Daten teilen. Clients innerhalb dieser Clientgruppe teilen ihren Status auch dann, wenn sie offline sind.
Client Group verwendet einen persistenten Cache auf der Festplatte, der durch den Namensparameter des Replicache-Konstruktors unterschieden wird. Alle Clients, die zu einer Clientgruppe mit demselben Namen gehören, teilen sich denselben Cache.
Der Client verfügt über eine geordnete Karte von Schlüssel-Wert-Paaren im persistenten Cache, die als Client-Ansicht bezeichnet wird. Die Clientansicht enthält Anwendungsdaten und wird mit Serverdaten synchronisiert. Der Grund für den Namen „Client View“ liegt darin, dass verschiedene Clients möglicherweise Serverdaten in unterschiedlichen Client Views haben. Dies bedeutet, dass jeder Client den Status des Servers anders sieht.
Der Zugriff auf die Client-Ansicht erfolgt sehr schnell. Die Leselatenz beträgt weniger als 1 ms und die meisten Geräte haben einen Durchsatz von 500 MB/s.
Es wird empfohlen, dass Sie es direkt aus der Client-Ansicht lesen und verwenden, anstatt die Client-Ansicht separat mit useState von einem Ort wie React zu kopieren und in den Speicher hochzuladen. Wenn der Mutator die Client-Ansicht ändert, wird das Abonnement ausgelöst, sodass die Benutzeroberfläche aktualisiert wird
Die Subscribe-Funktion empfängt das ReadTransaction-Argument und implementiert das Lesen aus Replicache. Immer wenn dieses Abonnement aufgrund einer Änderung der Replikache-Daten nicht mehr aktuell ist, wird die Abonnementfunktion erneut ausgeführt. Wenn sich dieses Ergebnis ändert, wird der Wert aktualisiert und die Benutzeroberfläche wird ebenfalls aktualisiert.
Wenn Sie die Benutzeroberfläche über ein Abonnement konfigurieren, können Sie sie immer auf dem neuesten Stand halten.
import {Replicache} from "replicache"; const rep = new Replicache({ name: userID, ... }); console.log(rep.clientID);
Mutation bezieht sich auf die Aufgabe, Replicache-Daten zu ändern. Das Subjekt, das Mutationen empfängt und tatsächlich Daten ändert, wird Mutator genannt.
Beim Start werden mehrere Mutatoren in Replicache registriert, aber es handelt sich eigentlich nur um benannte Funktionen. Sowohl createTodo als auch markTodoComplete unten sind Mutatoren, die Replicache-Daten über WriteTransaction ändern.
const todos = useSubscribe(rep, async tx => { return await tx.scan({prefix: 'todo/'}).toArray(); }); return ( <ul> {todos.map(todo => ( <li key={todo.id}>{todo.text}</li> ))} </ul> );
Mutator funktioniert wie folgt. Wenn der Mutator ausgeführt wird, ändern sich die Daten und die damit verbundenen Abonnements werden ausgelöst, und auch die Benutzeroberfläche ändert sich.
const rep = new Replicache({ ... mutators: { createTodo, markTodoComplete, }, }); async function createTodo(tx: WriteTransaction, todo: Todo) { await tx.set(`/todo/${todo.id}`, todo); } async function markTodoComplete(tx: WriteTransaction, {id, complete}: {id: string, complete: boolean}) { const key = `/todo/${id}`; const todo = await tx.get(key); if (!todo) { return; } todo.complete = complete; await tx.set(key, todo); }
Intern erzeugt Mutator etwas namens Mutation. Es ist wie ein Ausführungsdatensatz, aber Replicache erstellt die folgende Mutation.
await rep.mutate.createTodo({id: nanoid(), text: "take out the trash"});
Diese Mutationen werden als ausstehend markiert, bis sie auf den Server übertragen und vollständig synchronisiert werden.
Hier sind nun die Details von Sync, das als Kern von Replicache bezeichnet werden kann. Die Synchronisierung erfolgt auf dem Server.
(Von nun an bezieht sich der Ausdruck „Zustand“ auf den Zustand von Daten (Schlüssel-Wert-Raum), die aus mehreren Schlüssel-Wert-Paaren bestehen.)
Das Synchronisierungsproblem, das Replicache zu lösen versucht, tritt auf, wenn mehrere Clients gleichzeitig denselben Status ändern und die folgenden Bedingungen vorliegen.
Der letzte Punkt davon ist die „vernünftige Zusammenführung“ von Serveränderungen mit dem lokalen Status, was ein interessantes Thema ist. Für eine „rationale Fusion“ müssen die folgenden Situationen berücksichtigt werden.
Wenn lokale Änderungen noch nicht auf den Server angewendet wurden. In diesem Fall müssen Sie sicherstellen, dass lokale Änderungen nicht von der Benutzeroberfläche der App verschwinden, selbst wenn ein neuer Status vom Server abgerufen wird. Nach Erhalt des neuen Status vom Server müssen alle vorhandenen lokalen Änderungen zusätzlich zum Serverstatus erneut ausgeführt werden.
Wenn lokale Änderungen, die auf dem Client vorgenommen wurden, bereits an den Server gesendet und im Serverstatus widergespiegelt wurden. Achten Sie in diesem Fall darauf, lokale Änderungen nicht zweimal anzuwenden. Lokale Änderungen sollten nicht erneut angewendet werden
Wenn es andere Clients gibt, die den Serverstatus in denselben Status geändert haben. In diesem Fall müssen wie im ersten Fall lokale Änderungen basierend auf dem vom Server empfangenen Status erneut vorgenommen werden. Da jedoch Konflikte über dieselbe Ressource auftreten können, muss die Zusammenführungslogik sorgfältig geplant werden. Schreiben Sie diese Logik in den Mutator.
Lassen Sie uns den Betriebsablauf des Mutators verfolgen.
Der Mutator arbeitet lokal und der Wert des Replikache ändert sich entsprechend der Mutatorlogik. Gleichzeitig erstellt dieser Client eine Mutation mit einer mutationId, die sequenziell ansteigt. Mutationen werden als ausstehende Mutationen in die Warteschlange gestellt
Ausstehende Mutationen werden an den auf dem Server implementierten Push-Endpunkt (Replicache-Push) gesendet.
Mutation ändert den kanonischen Zustand, indem sie den auf dem Server implementierten Mutator ausführt. Beim Anwenden der Mutation wird die letzte Mutations-ID dieses Clients aktualisiert und wird zu einem Wert, der es Ihnen ermöglicht, zu wissen, ab welcher Mutation dieser Client den nächsten Pull erneut anwenden soll
Eine ausstehende Mutation, die lokal angewendet wird, generiert ein spekulatives Ergebnis, und eine auf dem Server angewendete Mutation generiert ein kanonisches Ergebnis. Auf dem Server angewendete Mutationen werden bestätigt und nicht erneut lokal ausgeführt. Auch wenn dieselbe Mutation ein anderes Ergebnis zurückgibt, hat das kanonische Ergebnis des Servers Vorrang, sodass sich das Ergebnis des Clients ändert
Replicache sendet regelmäßig eine Anfrage an den Pull-Endpunkt (replicache-pull), um den neuesten Status abzurufen und die Benutzeroberfläche zu aktualisieren.
Pull-Anfrage enthält Cookie und clientGroupId und gibt neues Cookie, Patch und lastMutationIDChanges zurück.
Cookie wird verwendet, um den vom Client gehaltenen Serverstatus zu unterscheiden. Jeder Wert, der verfolgen kann, wie stark sich die Server- und Client-Zustände unterscheiden, ist ausreichend. Sie können es sich als eine globale „Version“ vorstellen, die sich jedes Mal ändert, wenn sich der Status der Datenbank ändert. Alternativ können Sie eine Cookie-Strategie verwenden, um einen spezifischeren Datenbereich zu verfolgen.
lastMutationIdChanges ist ein Wert, der die zuletzt vom Server für jeden Client angewendete Mutations-ID darstellt. Alle Mutationen mit einer Mutations-ID kleiner als dieser Wert sollten nicht mehr als ausstehend, sondern bestätigt betrachtet werden.
Wenn ein Client einen Pull erhält, muss der Patch auf den lokalen Staat angewendet werden. Da sich die ausstehende Mutation jedoch auf den aktuellen lokalen Zustand ausgewirkt hätte, kann der Patch nicht direkt auf den lokalen Staat angewendet werden. Machen Sie stattdessen die lokal ausstehende Mutation rückgängig, wenden Sie zuerst den als Pull empfangenen Patch an und wenden Sie dann die lokal ausstehende Mutation erneut an.
Um diese Art des Rückgängigmachens und erneuten Anwendens zu ermöglichen, wurde Replicache ähnlich wie Git entwickelt. Sie können sich den Status des Servers als Hauptzweig vorstellen und den durch eine lokal anstehende Mutation geänderten Status als Entwicklungszweig, einen Pull vom Server zum Hauptzweig empfangen und die Entwicklung auf den Hauptzweig umbasieren.
Konflikte, die beim Rebase auftreten können, werden im Folgenden gesondert besprochen.
Poke ist, wie oben erläutert, eine Hinweisnachricht, die der Server dem Client zum Pullen auffordert.
Merge-Konflikte sind in verteilten Systemen wie Replicache unvermeidbar. Während des Pull- und Push-Vorgangs ist eine Zusammenführung erforderlich. Das Zusammenführen sollte auf eine Weise erfolgen, die das Zusammenführungsergebnis vorhersehbar macht und zum Zweck der App passt.
Wenn es sich um eine Konferenzraum-Reservierungs-App handelt, sollte bei Auftreten eines Konflikts nur eine Anfrage genehmigt werden. Daher müssen Sie eine Zusammenführungsmethode anwenden, die nur Kunden genehmigt, die zuerst Reservierungen vorgenommen haben.
Wenn es sich hingegen um eine Todo-App handelt, besteht der Zweck der Todo-Liste darin, dass beide Änderungen genehmigt werden, auch wenn Ergänzungen gleichzeitig erfolgen.
Ein Zusammenführungskonflikt tritt in den folgenden zwei Situationen auf.
Wenn lokale Änderungen auf den Server angewendet werden. Dies liegt daran, dass der Status bei lokaler Anwendung und der Status bei Anwendung auf dem Server unterschiedlich sein können.
Beim Umbasieren. Dies liegt daran, dass der Status bei der Anwendung unterschiedlich sein kann.
Replicache erkennt, dass die Zusammenführungsmethode je nach Zweck der App unterschiedlich implementiert werden muss, sodass Entwickler sie implementieren können. Entwickler können diese Logik über Mutator implementieren.
Das obige ist der detaillierte Inhalt vonReplicache Big Picture. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!