Cambio rotundo: métodos de sincronización para AccessHandles

El sistema de archivos privados de origen proporciona acceso a un tipo especial de archivo altamente optimizado para el rendimiento, por ejemplo, al ofrecer acceso de escritura in situ y exclusivo al contenido de un archivo. Los desarrolladores pueden obtener acceso a esos archivos llamando a createSyncAccessHandle(), que es un método expuesto en objetos FileSystemFileHandle. Esta llamada da como resultado una FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle es un primitivo de archivo que proporciona acceso eficaz a los archivos locales. Uno de sus principales casos de uso son las aplicaciones que portan código C/C++ a Wasm. Sin embargo, las llamadas asíncronas aún no son totalmente compatibles con Wasm, y el uso de la biblioteca Asyncify como alternativa disminuyó el rendimiento considerablemente. Hacer que todos los métodos de la FileSystemSyncAccessHandle sean síncronas coincidan con las que esperan las aplicaciones de Wasm de la API de archivos síncronos y tipo POSIX, lo que hace que la API sea más ergonómica, al mismo tiempo que proporciona importantes mejoras de rendimiento.

Novedades

FileSystemSyncAccessHandle expone los siguientes métodos que solían ser asíncronos, pero que son síncronos a partir de Chromium 108.

  • truncate(newSize): Cambia el tamaño del archivo asociado con el controlador de acceso para que tenga newSize bytes de longitud. Si newSize es más grande que el tamaño del archivo actual, se rellena el archivo con bytes nulos; de lo contrario, se trunca el archivo.
  • getSize(): Muestra el tamaño del archivo asociado con el controlador de acceso en bytes.
  • flush(): Garantiza que el contenido del archivo asociado con el controlador de acceso contenga todas las modificaciones realizadas a través de write().
  • close(): Limpia el controlador de acceso y, luego, lo cierra. Cerrar una manija de acceso inhabilita cualquier operación adicional en ella y libera la cerradura en la entrada asociada a la manija de acceso.
// 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();

¿Qué tengo que hacer?

Ten en cuenta que cambiar los métodos de asíncronos a síncronos es un cambio expuesto en la Web con una posible falla. Si bien el uso de await en métodos síncronos es una no-op, cualquier uso de Promise.then() fallará. Si encadenas una llamada a then() en el resultado de cualquiera de los métodos previamente asíncronos y ahora síncronos, debes cambiar el 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 */