Die beste Methode, um die Racebedingung in mehreren chrome.storage-API-Aufrufen zu verhindern?

8
  1. Etwas fordert eine Aufgabe an
  2. Etwas anderes zieht die Aufgabenliste aus dem Speicher und überprüft, ob dort Aufgaben vorhanden sind.
  3. Wenn es Aufgaben gibt, wird eine gelöscht und die kleinere "Aufgabenliste" wird wieder eingelagert.

Zwischen den Schritten 2 und 3 kann eine Race-Bedingung auftreten, wenn mehrere Anforderungen auftreten und die gleiche Aufgabe zweimal ausgeführt wird.

Ist die korrekte Auflösung, um die "Aufgaben-Tabelle" zu "sperren", während eine einzelne Aufgabe "ausgecheckt" ist, um weitere Anfragen zu verhindern?

Was ist die Lösung mit den geringsten Auswirkungen auf die Leistung, wie z. B. die Verzögerung der Ausführung und wie sollte sie in JavaScript mit der chrome.storage-API implementiert werden?

Ein Beispielcode:

%Vor%     
Cris Stringfellow 24.02.2013, 10:33
quelle

1 Antwort

4

Ich denke, Sie können ohne eine Sperre auskommen, indem Sie die Tatsache ausnutzen, dass JavaScript innerhalb eines Kontextes single-threaded ist, sogar mit der asynchronen chrome.storage-API. Solange Sie nicht chrome.storage.sync verwenden, ist das - wenn es Änderungen in der Cloud gibt oder nicht, denke ich, dass alle Wetten deaktiviert sind.

Ich würde so etwas tun (aus dem Ärmel geschüttelt, nicht getestet, keine Fehlerbehandlung):

%Vor%

Dies speichert Aufgabenanforderungen von Verbrauchern als Rückrufe in einer Warteschlange im lokalen Speicher. Wenn eine neue Anforderung eingeht, wird der Rückruf zur Warteschlange hinzugefügt und die Aufgabenliste wird abgerufen, wenn dies die einzige Anforderung in der Warteschlange ist. Andernfalls können wir annehmen, dass die Warteschlange bereits verarbeitet wird (dies ist eine implizite Sperre, die nur einem Ausführungsstrang erlaubt, auf die Aufgabenliste zuzugreifen).

Wenn die Aufgabenliste abgerufen wird, werden Aufgaben an Anfragen verteilt. Beachten Sie, dass mehr als eine Anforderung vorhanden sein kann, wenn weitere eingetroffen sind, bevor der Abruf abgeschlossen wurde. Dieser Code übergibt null an einen Rückruf, wenn mehr Anforderungen als Aufgaben vorhanden sind. Um stattdessen Anforderungen zu blockieren, bis weitere Aufgaben eintreffen, halten Sie nicht verwendete Rückrufe und starten Sie die Anforderungsverarbeitung neu, wenn Aufgaben hinzugefügt werden. Wenn Aufgaben sowohl dynamisch produziert als auch konsumiert werden können, sollten Sie daran denken, dass auch dort Rennbedingungen verhindert werden müssen, aber hier nicht angezeigt werden.

Es ist wichtig, das erneute Lesen der Aufgabenliste zu verhindern, bis die aktualisierte Aufgabenliste gespeichert ist. Um dies zu erreichen, werden Anforderungen nicht aus der Warteschlange entfernt, bis die Aktualisierung abgeschlossen ist. Dann müssen wir sicherstellen, dass alle Anfragen, die in der Zwischenzeit angekommen sind, verarbeitet werden (es ist möglich, den Aufruf von chrome.storage.local.get () kurz zu halten, aber ich habe es der Einfachheit halber so gemacht).

Dieser Ansatz sollte in dem Sinne ziemlich effizient sein, dass er Aktualisierungen der Aufgabenliste minimiert und dabei so schnell wie möglich reagiert. Es gibt kein explizites Sperren oder Warten. Wenn Sie über Aufgabenkonsumenten in anderen Kontexten verfügen, richten Sie einen chrome.extension-Nachrichtenhandler ein, der die Funktion getTask () aufruft.

    
rhashimoto 01.03.2013, 17:14
quelle