API Web Locks
(developer.mozilla.org)- A API Web Locks permite adquirir um lock de forma assíncrona em uma aba ou Web Worker, executar uma tarefa e depois liberar o lock
- Enquanto o lock estiver ativo, outros scripts da mesma origin não podem adquirir o mesmo lock, permitindo coordenar recursos com segurança entre várias abas ou workers
- Só pode ser usada em Secure Context (HTTPS) e está disponível em Web Workers
Principais conceitos e como usar
- Um lock é um recurso abstrato identificado por um nome definido pela aplicação web
- Por exemplo, ao sincronizar IndexedDB e rede em várias abas, é possível usar um lock chamado “my_net_db_sync” para que apenas uma aba execute a sincronização por vez
- Fluxo de uso:
- Solicitar o lock
- Executar a tarefa assíncrona
- Ao concluir a tarefa, o lock é liberado automaticamente
Código de exemplo
navigator.locks.request("my_resource", async (lock) => {
await do_something();
await do_something_else();
});
- Enquanto o lock estiver ativo, outras solicitações para o mesmo lock são adicionadas à fila, e quando o lock é liberado a primeira solicitação é processada
Opções
- mode: o modo padrão é “exclusive” (exclusivo), mas “shared” (compartilhado) também é possível. “exclusive” permite apenas uma solicitação, “shared” pode permitir várias
- ifAvailable: se não for possível adquirir o lock imediatamente, a solicitação falha e o callback retorna null
- steal: libera um lock existente com o mesmo nome e prioriza a nova solicitação
- signal: permite cancelar a solicitação com AbortSignal (por exemplo, para implementar timeout)
Monitoramento
- É possível consultar o estado atual dos locks da origin com
navigator.locks.query() - Isso é útil para depuração, permitindo verificar quais locks estão ativos e quais locks foram solicitados
Uso avançado
- Para controlar explicitamente o momento de conclusão de uma tarefa assíncrona, é possível retornar uma Promise
let resolve;
const p = new Promise((res) => { resolve = res });
navigator.locks.request("my_resource", (lock) => p);
- Ao chamar resolve(), o lock é liberado
Prevenção de deadlock
- Deadlock é uma situação em que solicitações diferentes entram em conflito por causa da ordem e o progresso se torna impossível
- Por exemplo, se a aba 1 tem o lock A e a aba 2 tem o lock B, e então a aba 1 solicita o lock B enquanto a aba 2 solicita o lock A, ambas ficam esperando
- Para evitar isso:
- Não aninhar solicitações de lock
- Respeitar uma ordem fixa nas solicitações de lock
- Definir timeout para interromper a solicitação
Interfaces
- Lock: fornece o nome e o modo do lock solicitado
- LockManager: fornece métodos para solicitar novos locks ou consultar locks existentes
- A instância pode ser obtida via
navigator.locks WorkerNavigator.lockspode ser usado em Web Workers
Especificação e suporte de navegadores
- Especificação: Web Locks API
- Compatibilidade de navegadores: suportada apenas em alguns navegadores; a disponibilidade nos navegadores mais recentes pode ser verificada no MDN
Opinião do GN⁺
- A API Web Locks é útil para resolver problemas de sincronização de recursos em ambientes assíncronos
- Como há possibilidade de deadlock, é preciso cuidado no uso e vale considerar mecanismos de segurança como timeout
- O modo shared pode melhorar o desempenho em tarefas somente leitura, mas ainda exige uma análise cuidadosa de condições de corrida
- Essa API pode ser usada como alternativa para resolver problemas de sincronização que existem com localStorage ou IndexedDB
Ainda não há comentários.