API de Web Locks
(developer.mozilla.org)- 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:
- Solicitar el lock
- Realizar la tarea asíncrona
- 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 variasifAvailable: si no se puede adquirir el lock de inmediato, la solicitud falla y el callback devuelve nullsteal: libera un lock existente con el mismo nombre y da prioridad a la nueva solicitudsignal: permite abortar la solicitud medianteAbortSignal(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 solicitadoLockManager: ofrece métodos para solicitar nuevos locks o consultar locks existentes- Se puede obtener una instancia con
navigator.locks WorkerNavigator.locksestá 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
localStorageo IndexedDB
Aún no hay comentarios.