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 est le portage 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 en tant qu'alternative 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 en octets du fichier associé au handle d'accès.
  • 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. La fermeture d'un handle d'accès désactive toute autre opération sur celui-ci et libère le verrou sur l'entrée associée à ce dernier.
// 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 de méthodes asynchrones à des méthodes synchrones est une modification exposée sur le Web susceptible de causer une panne. Bien que l'utilisation de await dans des méthodes synchrones soit une opération no-op, toute utilisation de Promise.then() échouera. 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 */