20 puntos por GN⁺ 2024-11-13 | Aún no hay comentarios. | Compartir por WhatsApp
  • La API de Web Locks permite adquirir un lock de forma asíncrona en una pestaña o un Web Worker, realizar una tarea y luego liberar el lock
  • Mientras el lock se mantiene, otros scripts dentro del mismo origin no pueden adquirir el mismo lock, por lo que se pueden coordinar recursos de forma segura entre varias pestañas o workers
  • Solo se puede usar en Secure Context (HTTPS) y está disponible en Web Workers

Conceptos principales y cómo usarla

  • Un lock es un recurso abstracto identificado por un nombre definido por la aplicación web
  • Por ejemplo, cuando varias pestañas hacen sincronización de IndexedDB y de red, se puede usar un lock llamado “my_net_db_sync” para que solo una pestaña realice la sincronización a la vez
  • Flujo de uso:
    1. Solicitar el lock
    2. Realizar la tarea asíncrona
    3. Al terminar la tarea, el lock se libera automáticamente

Código de ejemplo

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

  • Mientras el lock se mantiene, otras solicitudes para el mismo lock se agregan a la cola, y cuando el lock se libera, se procesa la primera solicitud

Opciones

  • mode: el modo predeterminado es “exclusive” (exclusivo), y también se puede usar el modo “shared” (compartido). “exclusive” permite solo una solicitud, mientras que “shared” puede permitir varias
  • ifAvailable: si no se puede adquirir el lock de inmediato, la solicitud falla y el callback devuelve null
  • steal: libera un lock existente con el mismo nombre y da prioridad a la nueva solicitud
  • signal: permite abortar la solicitud mediante AbortSignal (por ejemplo, para implementar un timeout)

Monitoreo

  • Se puede consultar el estado de los locks del origin actual usando navigator.locks.query()
  • Esto es útil para depuración, ya que permite revisar qué locks están activos y cuáles han sido solicitados

Uso avanzado

  • Si se quiere controlar explícitamente el momento en que termina una tarea asíncrona, se puede devolver una Promise

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

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

  • Al llamar a resolve(), el lock se libera

Prevención de deadlocks

  • Un deadlock es una situación en la que distintas solicitudes chocan por un problema de orden y ya no pueden avanzar
  • Por ejemplo, si la pestaña 1 tiene el lock A y la pestaña 2 tiene el lock B, y luego la pestaña 1 solicita el lock B mientras la pestaña 2 solicita el lock A, ambas quedan esperando mutuamente
  • Para evitarlo:
  • No anidar solicitudes de locks
  • Mantener un orden al solicitar locks
  • Configurar timeouts para abortar solicitudes

Interfaces

  • Lock: proporciona el nombre y el modo del lock solicitado
  • LockManager: ofrece métodos para solicitar nuevos locks o consultar locks existentes
  • Se puede obtener una instancia con navigator.locks
  • WorkerNavigator.locks está disponible en Web Workers

Especificación y soporte de navegadores

  • Especificación: Web Locks API
  • Compatibilidad de navegadores: solo está soportada en algunos navegadores; se puede verificar su disponibilidad en navegadores recientes en MDN

Opinión de GN⁺

  • La API de Web Locks es útil para resolver problemas de sincronización de recursos en entornos asíncronos
  • Como existe la posibilidad de deadlocks, hay que usarla con cuidado y considerar mecanismos de seguridad como timeouts
  • El modo shared puede mejorar el rendimiento en tareas de solo lectura, pero aun así requiere una revisión cuidadosa de las condiciones de carrera
  • Esta API puede servir como alternativa para resolver problemas de sincronización que existen con localStorage o IndexedDB

Aún no hay comentarios.

Aún no hay comentarios.