Stockage hautes performances pour votre application: API Storage Foundation

La plate-forme Web offre de plus en plus aux développeurs les outils dont ils ont besoin pour créer des applications hautes performances minutieuses pour le Web. En particulier, WebAssembly (Wasm) a ouvert la voie à des applications Web rapides et puissantes, tandis que des technologies comme Emscripten permettent désormais aux développeurs de réutiliser du code éprouvé sur le Web. Pour exploiter pleinement ce potentiel, les développeurs doivent disposer de la même puissance et flexibilité en matière de stockage.

C'est là que l'API Storage Foundation entre en jeu. L'API Storage Foundation est une nouvelle API de stockage rapide et non formulée qui permet de débloquer de nouveaux cas d'utilisation très demandés pour le Web, tels que l'implémentation de bases de données performantes et la gestion optimale des fichiers temporaires volumineux. Grâce à cette nouvelle interface, les développeurs peuvent "utiliser leur propre espace de stockage" sur le Web, ce qui réduit l'écart de fonctionnalités entre le code Web et le code spécifique à la plate-forme.

L'API Storage Foundation est conçue pour ressembler à un système de fichiers très basique. Elle offre donc aux développeurs davantage de flexibilité en fournissant des primitives génériques, simples et performantes sur lesquelles ils peuvent créer des composants de niveau supérieur. Les applications peuvent exploiter l'outil le plus adapté à leurs besoins afin de trouver le bon équilibre entre facilité d'utilisation, performances et fiabilité.

Pourquoi le Web a-t-il besoin d'une autre API de stockage ?

La plate-forme Web offre aux développeurs un certain nombre d'options de stockage, chacune étant conçue pour des cas d'utilisation spécifiques.

  • Certaines de ces options ne coïncident clairement pas avec cette proposition, car elles ne permettent de stocker que de très faibles quantités de données, comme les cookies ou l'API Web Storage composée des mécanismes sessionStorage et localStorage.
  • D'autres options sont déjà obsolètes pour diverses raisons, telles que l'API File and Directory Entry ou WebSQL.
  • L'API File System Access possède une surface d'API similaire, mais elle permet d'interagir avec le système de fichiers du client et de fournir un accès à des données qui peuvent ne pas appartenir à l'origine ni même au navigateur. Cette approche différente implique des considérations de sécurité plus strictes et des coûts de performances plus élevés.
  • L'API IndexedDB peut être utilisée comme backend pour certains cas d'utilisation de l'API Storage Foundation. Par exemple, Emscripten inclut IDBFS, un système de fichiers persistant basé sur IndexedDB. Cependant, comme IndexedDB est fondamentalement un magasin de clés-valeurs, ses performances sont limitées. De plus, l'accès direct aux sous-sections d'un fichier est encore plus difficile et plus lent sous IndexedDB.
  • Enfin, l'interface CacheStorage est largement acceptée et conçue pour stocker des données de grande taille telles que des ressources d'application Web, mais les valeurs sont immuables.

L'API Storage Foundation cherche à combler toutes les lacunes des options de stockage précédentes en permettant le stockage performant des fichiers volumineux modifiables définis dans l'origine de l'application.

Cas d'utilisation suggérés pour l'API Storage Foundation

Voici quelques exemples de sites qui peuvent utiliser cette API:

  • Applications de productivité ou de créativité qui utilisent de grandes quantités de données vidéo, audio ou image. Ces applications peuvent décharger des segments sur le disque au lieu de les conserver en mémoire.
  • Applications qui reposent sur un système de fichiers persistant accessible à partir de Wasm et qui nécessitent plus de performances que ce que peut garantir IDBFS

Qu'est-ce que l'API Storage Foundation ?

L'API se compose de deux éléments principaux:

  • Les appels de système de fichiers, qui fournissent des fonctionnalités de base pour interagir avec les fichiers et leurs chemins d'accès.
  • Les poignés de fichiers, qui fournissent un accès en lecture et en écriture à un fichier existant

Appels de système de fichiers

L'API Storage Foundation introduit un nouvel objet, storageFoundation, qui réside sur l'objet window et qui inclut un certain nombre de fonctions:

  • storageFoundation.open(name): ouvre le fichier portant le nom donné s'il existe et crée un autre fichier. Renvoie une promesse qui se résout avec le fichier ouvert.
  • storageFoundation.delete(name): supprime le fichier portant le nom donné. Renvoie une promesse qui se résout lorsque le fichier est supprimé.
  • storageFoundation.rename(oldName, newName): remplace le fichier de l'ancien nom par le nouveau de manière atomique. Affiche une promesse qui se résout lorsque le fichier est renommé.
  • storageFoundation.getAll(): renvoie une promesse qui se résout avec un tableau de tous les noms de fichiers existants.
  • storageFoundation.requestCapacity(requestedCapacity): demande une nouvelle capacité (en octets) à utiliser dans le contexte d'exécution actuel. Affiche une promesse résolue avec la capacité restante disponible.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity): libère le nombre d'octets spécifié du contexte d'exécution actuel et renvoie une promesse qui se résout avec la capacité restante.
  • storageFoundation.getRemainingCapacity(): renvoie une promesse qui se résout avec la capacité disponible pour le contexte d'exécution actuel.

Poignées de fichiers

L'utilisation des fichiers s'effectue via les fonctions suivantes:

  • NativeIOFile.close(): ferme un fichier et renvoie une promesse qui se résout une fois l'opération terminée.
  • NativeIOFile.flush(): synchronise (c'est-à-dire supprime) l'état en mémoire d'un fichier avec le périphérique de stockage, et renvoie une promesse qui se résout une fois l'opération terminée.
  • NativeIOFile.getLength(): renvoie une promesse qui se résout avec la longueur du fichier en octets.
  • NativeIOFile.setLength(length): définit la longueur du fichier en octets et renvoie une promesse qui se résout une fois l'opération terminée. Si la nouvelle longueur est inférieure à la longueur actuelle, les octets sont supprimés à partir de la fin du fichier. Sinon, le fichier est étendu avec des octets sans valeur.
  • NativeIOFile.read(buffer, offset): lit le contenu du fichier au décalage donné dans un tampon résultant du transfert du tampon donné, qui est ensuite dissocié. Renvoie une NativeIOReadResult avec le tampon transféré et le nombre d'octets lus.

    Un NativeIOReadResult est un objet qui comprend deux entrées:

    • buffer: ArrayBufferView, qui résulte du transfert du tampon transmis à read(). Il est du même type et de la même longueur que le tampon source.
    • readBytes: nombre d'octets lus dans buffer. Elle peut être inférieure à la taille de la mémoire tampon si une erreur se produit ou si la plage de lecture s'étend au-delà de la fin du fichier. Elle est définie sur zéro si la plage de lecture se situe au-delà de la fin du fichier.
  • NativeIOFile.write(buffer, offset): écrit le contenu du tampon donné dans le fichier avec le décalage spécifié. Le tampon est transféré avant que les données ne soient écrites et est donc dissocié. Renvoie NativeIOWriteResult avec le tampon transféré et le nombre d'octets écrits. Le fichier sera étendu si la plage d'écriture dépasse sa longueur.

    Un NativeIOWriteResult est un objet qui comprend deux entrées:

    • buffer: ArrayBufferView résultant du transfert du tampon transmis à write(). Il est du même type et de la même longueur que le tampon source.
    • writtenBytes: nombre d'octets écrits avec succès dans buffer. Cette taille peut être inférieure à la taille de la mémoire tampon en cas d'erreur.

Exemples complets

Pour clarifier les concepts présentés ci-dessus, voici deux exemples complets qui vous guident à travers les différentes étapes du cycle de vie des fichiers Storage Foundation.

Ouverture, rédaction, lecture, bouclage

// Open a file (creating it if needed).
const file = await storageFoundation.open('test_file');
try {
  // Request 100 bytes of capacity for this context.
  await storageFoundation.requestCapacity(100);

  const writeBuffer = new Uint8Array([64, 65, 66]);
  // Write the buffer at offset 0. After this operation, `result.buffer`
  // contains the transferred buffer and `result.writtenBytes` is 3,
  // the number of bytes written. `writeBuffer` is left detached.
  let result = await file.write(writeBuffer, 0);

  const readBuffer = new Uint8Array(3);
  // Read at offset 1. `result.buffer` contains the transferred buffer,
  // `result.readBytes` is 2, the number of bytes read. `readBuffer` is left
  // detached.
  result = await file.read(readBuffer, 1);
  // `Uint8Array(3) [65, 66, 0]`
  console.log(result.buffer);
} finally {
  file.close();
}

Ouverture, liste, suppression

// Open three different files (creating them if needed).
await storageFoundation.open('sunrise');
await storageFoundation.open('noon');
await storageFoundation.open('sunset');
// List all existing files.
// `["sunset", "sunrise", "noon"]`
await storageFoundation.getAll();
// Delete one of the three files.
await storageFoundation.delete('noon');
// List all remaining existing files.
// `["sunrise", "noon"]`
await storageFoundation.getAll();

Démonstration

Vous pouvez jouer avec la démonstration de l'API Storage Foundation dans l'intégration ci-dessous. Créez, renommez, lisez et écrivez des fichiers, et consultez la capacité disponible que vous avez demandée à mesure que vous apportez des modifications. Vous trouverez le code source de la démonstration sur Glitch.

Sécurité et autorisations

L'équipe Chromium a conçu et mis en œuvre l'API Storage Foundation en suivant les principes fondamentaux définis dans la section Contrôler l'accès à des fonctionnalités puissantes de la plate-forme Web, y compris le contrôle utilisateur, la transparence et l'ergonomie.

Selon le même modèle que les autres API de stockage modernes sur le Web, l'accès à l'API Storage Foundation est lié à l'origine, ce qui signifie qu'une origine ne peut accéder qu'aux données créées par l'utilisateur. Elle est également limitée aux contextes sécurisés.

Contrôle des utilisateurs

Le quota de stockage sera utilisé pour distribuer l'accès à l'espace disque et éviter toute utilisation abusive. La mémoire que vous souhaitez occuper doit d'abord être demandée. Comme les autres API de stockage, les utilisateurs peuvent libérer l'espace occupé par l'API Storage Foundation via leur navigateur.

Liens utiles

Remerciements

L'API Storage Foundation a été spécifiée et mise en œuvre par Emanuel Krivoy et Richard Stotz. Cet article a été examiné par Pete LePage et Joe Medley.

Image héros via Markus Spiske sur Unsplash.