Modification destructive: méthodes de synchronisation pour AccessHandles

Le système de fichiers privés d'origine donne accès à un type spécial de fichier hautement optimisé pour les performances, par exemple en offrant un accès en écriture sur place et exclusif au contenu d'un fichier. Les développeurs peuvent accéder à ces fichiers en appelant createSyncAccessHandle(), une méthode exposée sur les objets FileSystemFileHandle. Cet appel génère une erreur 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 de 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. Rendre toutes les méthodes de FileSystemSyncAccessHandle synchrones correspondent à l'API de fichier synchrone de type POSIX basée sur Wasm attendue. Cela rend l'API plus ergonomique tout en améliorant considérablement les performances.

Nouveautés

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

  • truncate(newSize): redimensionne le fichier associé à la poignée d'accès pour une longueur de newSize octets. Si newSize est supérieur à la taille actuelle du fichier, il le remplit avec des octets nuls. Sinon, il tronque le fichier.
  • getSize(): renvoie la taille du fichier associé au handle d'accès en octets.
  • flush(): vérifie que le contenu du fichier associé au handle d'accès contient toutes les modifications effectuées via write().
  • close(): vide la poignée d'accès, puis la ferme. La fermeture d'un handle d'accès désactive toutes les opérations supplémentaires effectuées sur celle-ci et libère le verrou sur l'entrée associée au handle 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 d'une méthode asynchrone à une méthode synchrone est un changement exposé sur le Web avec une faille potentielle. Bien que l'utilisation de await dans les méthodes synchrones soit une opération no-op, toute utilisation de Promise.then() ne fonctionnera pas. Si vous associez un appel then() au résultat de l'une des méthodes précédemment 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 */