20 Punkte von GN⁺ 2024-11-13 | Noch keine Kommentare. | Auf WhatsApp teilen
  • Die Web Locks API ermöglicht es, in einem einzelnen Tab oder Web Worker asynchron einen Lock zu erwerben, Arbeit auszuführen und den Lock anschließend wieder freizugeben
  • Solange der Lock gehalten wird, können andere Skripte innerhalb derselben Origin denselben Lock nicht erwerben, sodass sich Ressourcen über mehrere Tabs oder Worker hinweg sicher koordinieren lassen
  • Nur in Secure Contexts (HTTPS) verfügbar und in Web Workers nutzbar

Wichtige Konzepte und Verwendung

  • Ein Lock ist eine abstrakte Ressource, die durch einen von der Webanwendung definierten Namen identifiziert wird
  • Wenn beispielsweise mehrere Tabs IndexedDB und Netzwerksynchronisierung verwenden, kann mit einem Lock namens „my_net_db_sync“ sichergestellt werden, dass immer nur ein Tab gleichzeitig synchronisiert
  • Ablauf der Nutzung:
    1. Lock anfordern
    2. Asynchrone Arbeit ausführen
    3. Nach Abschluss der Arbeit wird der Lock automatisch freigegeben

Beispielcode

navigator.locks.request("my_resource", async (lock) => {
await do_something();
await do_something_else();
});

  • Während ein Lock gehalten wird, werden weitere Anfragen auf denselben Lock in eine Warteschlange gestellt; nach der Freigabe wird die erste Anfrage verarbeitet

Optionen

  • mode: Der Standardmodus ist „exclusive“ (exklusiv), alternativ ist auch „shared“ (geteilt) möglich. „exclusive“ erlaubt nur eine Anfrage, „shared“ mehrere
  • ifAvailable: Falls der Lock nicht sofort erworben werden kann, schlägt die Anfrage fehl; der Callback erhält null
  • steal: Hebt einen bestehenden Lock mit demselben Namen auf und priorisiert die neue Anfrage
  • signal: Über AbortSignal kann eine Anfrage abgebrochen werden (z. B. zur Implementierung eines Timeouts)

Monitoring

  • Mit navigator.locks.query() kann der aktuelle Lock-Status der Origin abgefragt werden
  • Das ist beim Debugging nützlich, um zu sehen, welche Locks gehalten werden und welche angefordert wurden

Fortgeschrittene Nutzung

  • Um den Abschlusszeitpunkt asynchroner Arbeit explizit zu steuern, kann ein Promise zurückgegeben werden

let resolve;
const p = new Promise((res) => { resolve = res });

navigator.locks.request("my_resource", (lock) => p);

  • Beim Aufruf von resolve() wird der Lock freigegeben

Deadlock-Vermeidung

  • Ein Deadlock ist eine Situation, in der verschiedene Anfragen aufgrund einer Reihenfolgeproblematik kollidieren und nicht weiterkommen
  • Beispielsweise hält Tab 1 Lock A und Tab 2 Lock B; wenn Tab 1 Lock B anfordert und Tab 2 Lock A anfordert, warten beide gegenseitig
  • Um das zu vermeiden:
  • Lock-Anfragen nicht verschachteln
  • Lock-Anfragen in einer festen Reihenfolge ausführen
  • Timeouts setzen, um Anfragen abzubrechen

Schnittstellen

  • Lock: Stellt Namen und Modus des angeforderten Locks bereit
  • LockManager: Bietet Methoden zum Anfordern neuer Locks oder zum Abfragen bestehender Locks
  • Eine Instanz ist über navigator.locks erhältlich
  • WorkerNavigator.locks ist in Web Workers verfügbar

Spezifikation und Browser-Unterstützung

  • Spezifikation: Web Locks API
  • Browser-Kompatibilität: Wird nur von einigen Browsern unterstützt; ob sie in aktuellen Browsern verfügbar ist, lässt sich auf MDN prüfen

Meinung von GN⁺

  • Die Web Locks API ist nützlich, um Probleme bei der Ressourcensynchronisierung in asynchronen Umgebungen zu lösen
  • Da Deadlocks möglich sind, ist beim Einsatz Vorsicht geboten; Schutzmechanismen wie Timeouts sollten berücksichtigt werden
  • Der Shared-Modus kann bei schreibgeschützten Aufgaben die Performance verbessern, erfordert aber weiterhin eine sorgfältige Prüfung auf Race Conditions
  • Diese API kann als Alternative genutzt werden, um bestehende Synchronisierungsprobleme von localStorage oder IndexedDB zu lösen

Noch keine Kommentare.

Noch keine Kommentare.