Alteração interruptiva: métodos de sincronização para AccessHandles

O sistema de arquivos particular de origem fornece acesso a um tipo especial de arquivo altamente otimizado para desempenho, por exemplo, oferecendo acesso de gravação no local e exclusivo ao conteúdo de um arquivo. Os desenvolvedores podem ter acesso a esses arquivos chamando createSyncAccessHandle(), que é um método exposto em objetos FileSystemFileHandle. Essa chamada resulta em um FileSystemSyncAccessHandle.

O FileSystemSyncAccessHandle é um primitivo de arquivo que fornece acesso de alto desempenho a arquivos locais. Um dos principais casos de uso são aplicativos que transferem o código C/C++ para o Wasm. No entanto, as chamadas assíncronas ainda não são totalmente compatíveis com o Wasm, e o uso da biblioteca Asyncify como alternativa teve uma performance significativamente prejudicada. Todos os métodos da FileSystemSyncAccessHandle são síncronos, e o aplicativo baseado no Wasm da API do arquivo POSIX é esperado. Isso torna a API mais ergonômica e proporciona ganhos significativos de desempenho.

O que há de novo?

FileSystemSyncAccessHandle expõe os métodos a seguir que eram assíncronos, mas que são síncronos desde o Chromium 108.

  • truncate(newSize): redimensiona o arquivo associado ao identificador de acesso para ter newSize bytes. Se newSize for maior que o tamanho atual do arquivo, ele preencherá o arquivo com bytes nulos. Caso contrário, o arquivo será truncado.
  • getSize(): retorna o tamanho do arquivo associado ao identificador de acesso em bytes.
  • flush(): garante que o conteúdo do arquivo associado ao identificador de acesso contenha todas as modificações feitas pelo write().
  • close(): limpa e fecha a alça de acesso. Fechar uma alça de acesso desativa todas as outras operações nela e libera o bloqueio na entrada associada a ela.
// In a `Worker`:
const root = await navigator.storage.getDirectory();
const fileHandle = await root.getFileHandle('test', { create: true });
// `createSyncAccessHandle()` is still async.
const accessHandle = await fileHandle.createSyncAccessHandle();
// Both `read()` and `write()` were sync before.
accessHandle.read(/* ... */);
accessHandle.write(/* ... */);

// New: synchronous as of Chromium 108.
console.log(accessHandle.getSize());
accessHandle.truncate(123);
accessHandle.flush();
accessHandle.close();

O que eu preciso fazer?

Mudar os métodos de assíncrono para síncrono é uma alteração exposta pela Web com possível falha. Embora o uso de await em métodos síncronos seja um ambiente autônomo, qualquer uso de Promise.then() vai ser interrompido. Se você encadear uma chamada then() no resultado de qualquer um dos métodos anteriormente assíncronos e agora síncronos, vai precisar mudar o código.

// (✅) This won't break, but you better remove the superfluous `await`:
await accessHandle.flush();
// ✅ Correct:
accessHandle.flush();
// ⛔️ This will break, and you need to restructure your code:
accessHandle.flush().then(/* Follow-up code */);
// ✅ Correct:
accessHandle.flush();
/* Follow-up code */