20 pontos por GN⁺ 2024-11-13 | Ainda não há comentários. | Compartilhar no WhatsApp
  • 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:
    1. Solicitar o lock
    2. Executar a tarefa assíncrona
    3. 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.locks pode 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.

Ainda não há comentários.