Высокопроизводительное хранилище для вашего приложения: API Storage Foundation

Веб-платформа все чаще предлагает разработчикам инструменты, необходимые для создания точно настроенных высокопроизводительных приложений для Интернета. В частности, WebAssembly (Wasm) открыл двери для быстрых и мощных веб-приложений, а такие технологии, как Emscripten, теперь позволяют разработчикам повторно использовать проверенный и проверенный код в Интернете. Чтобы по-настоящему использовать этот потенциал, разработчики должны обладать такими же возможностями и гибкостью, когда дело касается хранилища.

Именно здесь на помощь приходит Storage Foundation API. Storage Foundation API — это новый быстрый и независимый API хранилища, который открывает новые и востребованные варианты использования в Интернете, такие как реализация высокопроизводительных баз данных и корректное управление большими временными файлами. Благодаря этому новому интерфейсу разработчики могут «перенести в Интернет собственное хранилище», сокращая разрыв в функциях между веб-кодом и кодом, специфичным для платформы.

API Storage Foundation спроектирован так, чтобы напоминать очень простую файловую систему, поэтому он дает разработчикам гибкость, предоставляя универсальные, простые и производительные примитивы, на основе которых они могут создавать компоненты более высокого уровня. Приложения могут использовать лучший инструмент для своих нужд, находя правильный баланс между удобством использования, производительностью и надежностью.

Зачем Интернету нужен еще один API хранилища?

Веб-платформа предлагает разработчикам ряд вариантов хранения данных, каждый из которых создан с учетом конкретных вариантов использования.

  • Некоторые из этих опций явно не пересекаются с этим предложением, поскольку они позволяют хранить только очень небольшие объемы данных, например файлы cookie или API веб-хранилища, состоящий из механизмов sessionStorage и localStorage .
  • Другие параметры уже устарели по разным причинам, например, API записей файлов и каталогов или WebSQL .
  • API доступа к файловой системе имеет аналогичную поверхность API, но его использование предназначено для взаимодействия с файловой системой клиента и предоставления доступа к данным, которые могут находиться за пределами владения источника или даже браузера. Этот другой фокус связан с более строгими соображениями безопасности и более высокими затратами на производительность.
  • API IndexedDB можно использовать в качестве серверной части для некоторых вариантов использования API Storage Foundation. Например, Emscripten включает IDBFS , постоянную файловую систему на основе IndexedDB. Однако, поскольку IndexedDB по своей сути представляет собой хранилище значений ключей, оно имеет значительные ограничения производительности. Более того, прямой доступ к подразделам файла в IndexedDB еще сложнее и медленнее.
  • Наконец, интерфейс CacheStorage широко поддерживается и настроен для хранения данных большого размера, таких как ресурсы веб-приложений, но значения неизменяемы.

API Storage Foundation — это попытка закрыть все пробелы предыдущих вариантов хранения, обеспечивая эффективное хранение изменяемых больших файлов, определенных в исходном коде приложения.

Рекомендуемые варианты использования Storage Foundation API

Примеры сайтов, которые могут использовать этот API:

  • Приложения для повышения производительности и творчества, которые работают с большими объемами видео-, аудио- или графических данных. Такие приложения могут выгружать сегменты на диск вместо того, чтобы хранить их в памяти.
  • Приложения, использующие постоянную файловую систему, доступную из Wasm, и которым требуется более высокая производительность, чем может гарантировать IDBFS.

Что такое API Storage Foundation?

API состоит из двух основных частей:

  • Вызовы файловой системы , которые предоставляют базовые функции для взаимодействия с файлами и путями к файлам.
  • Дескрипторы файлов , которые обеспечивают доступ для чтения и записи к существующему файлу.

Вызовы файловой системы

API Storage Foundation представляет новый объект storageFoundation , который находится в объекте window и включает в себя ряд функций:

  • storageFoundation.open(name) : открывает файл с заданным именем, если он существует, и в противном случае создает новый файл. Возвращает обещание, которое разрешается с открытым файлом.
  • storageFoundation.delete(name) : удаляет файл с заданным именем. Возвращает обещание, которое выполняется при удалении файла.
  • storageFoundation.rename(oldName, newName) : атомарно переименовывает файл со старого имени на новое. Возвращает обещание, которое выполняется при переименовании файла.
  • storageFoundation.getAll() : возвращает обещание, которое разрешается с массивом всех существующих имен файлов.
  • storageFoundation.requestCapacity(requestedCapacity) : запрашивает новую емкость (в байтах) для использования текущим контекстом выполнения. Возвращает обещание, которое выполнено с учетом оставшегося объема доступной емкости.
  • storageFoundation.releaseCapacity(toBeReleasedCapacity) : освобождает указанное количество байтов из текущего контекста выполнения и возвращает обещание, которое разрешается с оставшейся емкостью.
  • storageFoundation.getRemainingCapacity() : возвращает обещание, которое разрешается с учетом емкости, доступной для текущего контекста выполнения.

Дескрипторы файлов

Работа с файлами происходит посредством следующих функций:

  • NativeIOFile.close() : закрывает файл и возвращает обещание, которое разрешается после завершения операции.
  • NativeIOFile.flush() : синхронизирует (то есть сбрасывает) состояние файла в памяти с устройством хранения и возвращает обещание, которое разрешается после завершения операции.
  • NativeIOFile.getLength() : возвращает обещание, которое разрешается с длиной файла в байтах.
  • NativeIOFile.setLength(length) : устанавливает длину файла в байтах и ​​возвращает обещание, которое разрешается после завершения операции. Если новая длина меньше текущей, байты удаляются, начиная с конца файла. В противном случае файл расширяется байтами с нулевым значением.
  • NativeIOFile.read(buffer, offset) : считывает содержимое файла по заданному смещению через буфер, который является результатом передачи данного буфера, который затем остается отключенным. Возвращает NativeIOReadResult с переданным буфером и количеством успешно прочитанных байтов.

    NativeIOReadResult — это объект, состоящий из двух записей:

    • buffer : ArrayBufferView , который является результатом передачи буфера, переданного в read() . Он того же типа и длины, что и исходный буфер.
    • readBytes : количество байтов, которые были успешно прочитаны в buffer . Это может быть меньше размера буфера, если возникает ошибка или диапазон чтения выходит за пределы конца файла. Он устанавливается в ноль, если диапазон чтения находится за пределами конца файла.
  • NativeIOFile.write(buffer, offset) : записывает содержимое данного буфера в файл по заданному смещению. Буфер передается до записи каких-либо данных и поэтому остается отключенным. Возвращает NativeIOWriteResult с переданным буфером и количеством успешно записанных байтов. Файл будет расширен, если диапазон записи превысит его длину.

    NativeIOWriteResult — это объект, состоящий из двух записей:

    • buffer : ArrayBufferView , который является результатом передачи буфера, переданного в write() . Он того же типа и длины, что и исходный буфер.
    • writtenBytes : количество байтов, которые были успешно записаны в buffer . В случае возникновения ошибки этот размер может быть меньше размера буфера.

Полные примеры

Чтобы сделать изложенные выше концепции более понятными, вот два полных примера, которые проведут вас через различные этапы жизненного цикла файлов Storage Foundation.

Открытие, написание, чтение, закрытие

// 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();
}

Открытие, листинг, удаление

// 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();

Демо

Вы можете поиграть с демо-версией Storage Foundation API, представленной ниже. Создавайте, переименовывайте, записывайте и читайте файлы, а также просматривайте доступную емкость, которую вы запрашивали, обновляя по мере внесения изменений. Вы можете найти исходный код демо-версии на Glitch.

Безопасность и разрешения

Команда Chromium разработала и реализовала API Storage Foundation, используя основные принципы, определенные в разделе «Управление доступом к мощным функциям веб-платформы» , включая пользовательский контроль, прозрачность и эргономику.

Следуя той же схеме, что и другие современные API-интерфейсы хранилища в Интернете, доступ к API Storage Foundation привязан к источнику, что означает, что источник может получать доступ только к самостоятельно созданным данным. Он также ограничен безопасными контекстами.

Пользовательский контроль

Квота хранилища будет использоваться для распределения доступа к дисковому пространству и предотвращения злоупотреблений. Память, которую вы хотите занять, необходимо сначала запросить. Как и другие API хранилища, пользователи могут очистить пространство, занимаемое Storage Foundation API, через свой браузер.

Полезные ссылки

Благодарности

API Storage Foundation был указан и реализован Эмануэлем Кривой и Ричардом Стоцем . Эту статью рецензировали Пит ЛеПейдж и Джо Медли .

Изображение героя предоставлено Маркусом Списке на Unsplash .