Критическое изменение: методы синхронизации для AccessHandles

Частная файловая система origin предоставляет доступ к особому типу файлов, который высоко оптимизирован для производительности, например, предлагая доступ на месте и эксклюзивный доступ для записи к содержимому файла. Разработчики могут получить доступ к таким файлам, вызвав createSyncAccessHandle() , который является методом, представленным в объектах FileSystemFileHandle . Этот вызов приводит к FileSystemSyncAccessHandle .

FileSystemSyncAccessHandle — это примитив файла, который обеспечивает производительный доступ к локальным файлам. Одним из основных вариантов его использования являются приложения, портирующие код C/C++ в Wasm; однако асинхронные вызовы пока не полностью поддерживаются в Wasm, а использование библиотеки Asyncify в качестве альтернативы существенно снизило производительность. Создание всех методов FileSystemSyncAccessHandle синхронными соответствует синхронному, POSIX-подобному API файла, ожидаемому приложением Wasm; делая API более эргономичным и обеспечивая существенный прирост производительности.

Что нового?

FileSystemSyncAccessHandle предоставляет следующие методы, которые раньше были асинхронными, но стали синхронными в Chromium 108 .

  • truncate(newSize) : Изменяет размер файла, связанного с дескриптором доступа, на newSize байтов. Если newSize больше текущего размера файла, он дополняет файл нулевыми байтами; в противном случае он усекает файл.
  • getSize() : возвращает размер файла, связанного с дескриптором доступа, в байтах.
  • flush() : гарантирует, что содержимое файла, связанного с дескриптором доступа, содержит все изменения, выполненные с помощью write() .
  • close() : очищает дескриптор доступа и затем закрывает его. Закрытие дескриптора доступа отключает любые дальнейшие операции над ним и снимает блокировку записи, связанной с дескриптором доступа.
// 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();

Что мне нужно сделать?

Обратите внимание, что изменение методов с асинхронных на синхронные — это изменение, которое может быть открыто для веба и может привести к поломке. Хотя использование await в синхронных методах является пустой операцией, любое использование Promise.then() приведет к поломке. Если вы связываете вызов then() с результатом любого из ранее асинхронных, а теперь синхронных методов, вам необходимо изменить свой код.

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

Частная файловая система origin предоставляет доступ к особому типу файлов, который высоко оптимизирован для производительности, например, предлагая доступ на месте и эксклюзивный доступ для записи к содержимому файла. Разработчики могут получить доступ к таким файлам, вызвав createSyncAccessHandle() , который является методом, представленным в объектах FileSystemFileHandle . Этот вызов приводит к FileSystemSyncAccessHandle .

FileSystemSyncAccessHandle — это примитив файла, который обеспечивает производительный доступ к локальным файлам. Одним из основных вариантов его использования являются приложения, портирующие код C/C++ в Wasm; однако асинхронные вызовы пока не полностью поддерживаются в Wasm, а использование библиотеки Asyncify в качестве альтернативы существенно снизило производительность. Создание всех методов FileSystemSyncAccessHandle синхронными соответствует синхронному, POSIX-подобному API файла, ожидаемому приложением Wasm; делая API более эргономичным и обеспечивая существенный прирост производительности.

Что нового?

FileSystemSyncAccessHandle предоставляет следующие методы, которые раньше были асинхронными, но стали синхронными в Chromium 108 .

  • truncate(newSize) : Изменяет размер файла, связанного с дескриптором доступа, на newSize байтов. Если newSize больше текущего размера файла, он дополняет файл нулевыми байтами; в противном случае он усекает файл.
  • getSize() : возвращает размер файла, связанного с дескриптором доступа, в байтах.
  • flush() : гарантирует, что содержимое файла, связанного с дескриптором доступа, содержит все изменения, выполненные с помощью write() .
  • close() : очищает дескриптор доступа и затем закрывает его. Закрытие дескриптора доступа отключает любые дальнейшие операции над ним и снимает блокировку записи, связанной с дескриптором доступа.
// 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();

Что мне нужно сделать?

Обратите внимание, что изменение методов с асинхронных на синхронные — это изменение, которое может быть открыто для веба и может привести к поломке. Хотя использование await в синхронных методах является пустой операцией, любое использование Promise.then() приведет к поломке. Если вы связываете вызов then() с результатом любого из ранее асинхронных, а теперь синхронных методов, вам необходимо изменить свой код.

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