Volver al Blog
Plataforma

Web Locks API: coordinar trabajo compartido con seguridad

Coordina pestañas, ventanas y workers con Web Locks API sin confundir los bloqueos del navegador con bloqueos distribuidos del servidor.

BotBrowser Team

Documentación

Quieres la documentación estructurada de Plataforma?

Este artículo forma parte de la biblioteca editorial. Para pasos de configuración, material de referencia y actualizaciones continuas, entra en la sección de docs.

Cuando varias pestañas o workers actualizan el mismo recurso del navegador, «comprobar y escribir» no coordina: dos contextos pueden pasar la comprobación a la vez. Web Locks API pone en cola solicitudes con nombre para que un solo contexto de un origen tenga la sección crítica. No coordina servidores ni orígenes distintos y no repara por sí sola el estado abandonado al cerrar una aplicación. BotBrowser puede repetir un perfil autorizado, pero no concede bloqueos ni sustituye la corrección de la aplicación y el servidor.

Flujo abstracto donde varios contextos del navegador convergen en una sección crítica serializada y vuelven a su trabajo.

TL;DR

  • Solicita el bloqueo alrededor de la operación compartida más pequeña y libéralo al devolver el callback.
  • Usa ifAvailable o un límite de tiempo de la aplicación cuando esperar no sea válido; una denegación no es una adquisición.
  • Un worker, una pestaña o una ventana pueden desaparecer. Haz la operación idempotente y deja la recuperación fuera del callback.
  • Web Locks coordina contextos del navegador del mismo origen, no páginas de otro origen, procesos arbitrarios del servidor ni pestañas ocultas.
  • BotBrowser puede repetir un flujo autorizado de perfil, pero la página conserva la responsabilidad de bloqueo, almacenamiento y cancelación.

Contenido

Modelo de bloqueo del navegador

navigator.locks.request(name, options, callback) pone en cola un bloqueo con nombre. El modo exclusivo es el predeterminado; el modo compartido permite varios lectores y excluye a un escritor exclusivo. El callback solo corre cuando el navegador concede el bloqueo, que dura hasta que el callback devuelve o su promise termina. Otro contexto del mismo origen espera en la cola, en vez de sondear una bandera de almacenamiento.

La cola no es un mutex global del backend: no cruza orígenes, perfiles, dispositivos ni instancias de servidor. Mantén corta la sección protegida: leer, validar un cambio, escribir y devolver. Las llamadas de red y esperas de interfaz suelen estar fuera del bloqueo; para decisiones que deben sobrevivir al cierre usa una transacción o un arrendamiento del servidor.

Un fixture de coordinación

Este fixture incrementa un contador local e informa si obtuvo el bloqueo. Con ifAvailable, lock es null cuando otro contexto es propietario.

async function incrementCounter(storage, report) {
  if (!navigator.locks) return report('unsupported');
  return navigator.locks.request('counter-write', { ifAvailable: true }, async lock => {
    if (!lock) return report('busy');
    const current = Number(storage.getItem('counter') || 0);
    storage.setItem('counter', String(current + 1));
    report('committed');
  });
}

Dos contextos concurrentes no entran a la vez; uno ocupado informa busy y un navegador sin la API informa unsupported. Es solo un ejemplo local: localStorage no es una base transaccional. Para datos importantes, usa almacenamiento adecuado y vuelve a validar conflictos en el servidor.

Seguridad del worker y recuperación

Un worker puede solicitar el mismo nombre que una ventana. Si termina mientras espera o dentro del callback, el navegador libera el bloqueo, pero la escritura parcial o el efecto externo siguen siendo responsabilidad de la aplicación. Usa una clave de idempotencia y distingue «no iniciado», «confirmado» y «desconocido tras interrupción». No mantengas el bloqueo mientras esperas una red lenta.

Evita colas ilimitadas para acciones del usuario. ifAvailable sirve para trabajo opcional; el trabajo obligatorio necesita un límite y comprobaciones de cancelación antes de cada paso irreversible. Devuelve siempre desde el callback y cierra los puertos del worker al apagarlo.

BotBrowser permite repetir flujos autorizados con perfiles para revisar compatibilidad. No concede Web Locks, no libera bloqueos de otra pestaña, no controla la planificación entre orígenes ni sustituye transacciones del servidor.

Evidencia y matriz de decisión

Prueba dos ventanas del mismo origen y un worker, con un nombre único, contador y terminación forzada del worker. Registra versión del navegador, perfil, modo headed/headless, almacenamiento, resultado visible y valor final; no guardes datos de cuentas ni capturas crudas.

ObservaciónInterpretación seguraSiguiente acción
Un committed por solicitud aceptadaLa sección se serializó en la pruebaManténla corta y repite tras actualizar
busy con ifAvailableEl bloqueo no estaba libreConserva el estado y decide un reintento visible
unsupportedFalta la API en el contextoUsa una alternativa o transacción de servidor
El worker termina antes del informeEl resultado puede ser desconocidoReconcilia por clave idempotente antes de reintentar
El contador es incorrecto pese a serializarAlmacenamiento o validación no son atómicosMueve el invariante a almacenamiento transaccional

La prueba demuestra comportamiento observable, no coordinación distribuida. Verifica también mensaje de estado, formulario conservado y reintento sin duplicar un compromiso.

Delimita el recurso y el callback

El nombre debe describir el recurso protegido, no la pantalla. Usa nombres separados para invariantes distintos y evita un bloqueo global que retrase trabajo independiente. El callback debe leer, validar, escribir y devolver; el bloqueo se libera cuando termina su promise. Las redes, esperas y animaciones van fuera.

Un rechazo libera el bloqueo, pero no demuestra que un efecto externo terminó. AbortController.abort() no revoca un callback ya iniciado: solo avisa al código que observa la señal. Comprueba la cancelación antes de cada paso irreversible y prepara reintentos idempotentes.

Owner ausente y límite de espera

Una pestaña, ventana o worker puede desaparecer. El navegador libera el bloqueo, pero la aplicación debe guardar una intención con clave idempotente y reconciliar su outbox: distingue no iniciado, confirmado y desconocido antes de repetir. Con ifAvailable, busy conserva el estado actual; el trabajo que espera necesita un plazo, nunca un bucle continuo.

Compatibilidad y revisión

Separa API presente, operación completada y resultado visible. Una cadena de versión no sustituye el fixture. Prueba API ausente, rechazo, fallo de almacenamiento y terminación del worker; conserva un estado accesible y un reintento usable con teclado. Revisa nombres, alternativa y retención cuando cambien navegador, almacenamiento o modo offline.

Conclusión

Usa Web Locks para coordinar brevemente contextos del mismo origen. Mantén escrituras atómicas, recupera interrupciones y coloca los invariantes duraderos en almacenamiento que sobreviva al navegador. El siguiente paso seguro es ejecutar el fixture de dos ventanas y worker con tu alternativa real y comprobar el registro final.

Preguntas frecuentes

¿Protege una fila del servidor?

No. Solo coordina contextos del navegador; el servidor necesita autorización, conflictos y una transacción o regla de idempotencia.

¿Puedo liberar un bloqueo por la fuerza al vencer un tiempo?

No. Se libera cuando termina el callback o el contexto propietario. Diseña cancelación y evita trabajo lento dentro del bloqueo.

¿ifAvailable significa que falló?

Significa que elegiste no esperar. null indica que no se ejecutó; conserva el estado y decide si ofrecer reintento.

¿BotBrowser hace determinista la planificación?

No. Hace repetible un flujo de perfil compatible, mientras la planificación, el almacenamiento y la recuperación siguen siendo responsabilidades de la página.

Fuentes y lecturas

Sources

#Web Locks API#Workers#Coordinación Del Navegador#Concurrencia

Lleva BotBrowser de la investigación a producción

Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.