Niezbędna zmiana: metody synchronizacji dla elementów AccessHandles

Prywatny system plików origin zapewnia dostęp do specjalnego rodzaju pliku, który jest wysoce zoptymalizowany pod kątem wydajności, np. przez oferowanie lokalnego i wyłącznego dostępu do treści zawartości pliku. Deweloperzy mogą uzyskać dostęp do takich plików, wywołując metodę createSyncAccessHandle(), która jest udostępniana w obiektach FileSystemFileHandle. Wynikiem tego wywołania jest FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle to podstawowa wersja pliku, która zapewnia skuteczny dostęp do plików lokalnych. Jednym z najważniejszych zastosowań tej aplikacji jest przenoszenie kodu C/C++ do Wasm. Jednak wywołania asynchroniczne nie są jeszcze w pełni obsługiwane przez Wasm, a korzystanie z biblioteki Asyncify jako alternatywy znacznie obniżyło wydajność. Wszystkie metody synchronicznego polecenia FileSystemSyncAccessHandle muszą być zgodne z synchroniczną, przypominającą interfejs POSIX aplikacji wykorzystującej interfejs Wasm do obsługi plików, co sprawia, że interfejs API jest bardziej ergonomiczny, a jednocześnie znacznie zwiększa jego wydajność.

Nowości

FileSystemSyncAccessHandle ujawnia poniższe metody, które wcześniej były asynchroniczne, ale są synchronizowane od wersji Chromium 108.

  • truncate(newSize): zmienia rozmiar pliku powiązanego z uchwytem na newSize B. Jeśli newSize jest większy niż bieżący rozmiar pliku, do pliku zostanie dodany zerowy bajtów. W przeciwnym razie plik zostanie obcięty.
  • getSize(): zwraca rozmiar pliku powiązanego z uchwytem dostępu w bajtach.
  • flush(): gwarantuje, że zawartość pliku powiązanego z uchwytem dostępu będzie zawierać wszystkie zmiany wprowadzone za pomocą write().
  • close(): opróżnia uchwyt dostępu, a następnie go zamyka. Zamknięcie uchwytu dostępu powoduje wyłączenie wszelkich dalszych operacji na nim i zwalnia blokadę wpisu powiązanego z uchwytem dostępu.
// 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();

Co muszę zrobić?

Pamiętaj, że zmiana metod z asynchronicznych na synchroniczne to zmiana widoczna w internecie, która może spowodować uszkodzenie. Chociaż korzystanie z metody await w metodach synchronicznych jest opcjonalne, korzystanie z metody Promise.then() może przestać działać. Jeśli łańcuch jest łańcuch wywołania then() w wyniku działania jednej z wcześniej asynchronicznych i teraz zsynchronizowanych metod, musisz zmienić swój kod.

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