Modification destructive: méthodes de synchronisation pour AccessHandles

Le système de fichiers privé d'origine fournit un accès à un type de fichier spécial hautement optimisé pour les performances, par exemple en offrant un accès en écriture exclusif et en place au contenu d'un fichier. Les développeurs peuvent accéder à ces fichiers en appelant createSyncAccessHandle(), qui est une méthode exposée sur les objets FileSystemFileHandle. Cet appel génère une FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle est une primitive de fichier qui fournit un accès performant aux fichiers locaux. L'un de ses principaux cas d'utilisation concerne les applications qui transfèrent du code C/C++ vers Wasm. Toutefois, les appels asynchrones ne sont pas encore entièrement compatibles avec Wasm, et l'utilisation de la bibliothèque Asyncify à la place a considérablement dégradé les performances. La synchronisation de toutes les méthodes de FileSystemSyncAccessHandle correspond à l'API de fichiers synchrone, semblable à POSIX, attendue par l'application Wasm. L'API est ainsi plus ergonomique, tout en offrant des gains de performances substantiels.

Nouveautés

FileSystemSyncAccessHandle expose les méthodes suivantes qui étaient auparavant asynchrones, mais qui sont synchrones à partir de Chromium 108.

  • truncate(newSize): redimensionne le fichier associé à la poignée d'accès pour qu'il mesure newSize octets. Si newSize est plus grand que la taille de fichier actuelle, le fichier est rempli d'octets nuls. Sinon, il est tronqué.
  • getSize(): renvoie la taille du fichier associé au handle d'accès en octets.
  • flush(): s'assure que le contenu du fichier associé au gestionnaire d'accès contient toutes les modifications effectuées via write().
  • close(): vide le gestionnaire d'accès, puis le ferme. Fermer un gestionnaire d'accès désactive toutes les autres opérations qui y sont effectuées et libère le verrouillage de l'entrée associée au gestionnaire d'accès.
// 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();

Que dois-je faire ?

Notez que le passage des méthodes asynchrones aux méthodes synchrones est une modification exposée sur le Web pouvant entraîner une interruption. Bien que l'utilisation de await dans des méthodes synchrones ne soit pas une opération, toute utilisation de Promise.then() entraînera une erreur. Si vous enchaînez un appel then() sur le résultat de l'une des méthodes auparavant asynchrones et désormais synchrones, vous devez modifier votre code.

// (✅) 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 */