Modifica irreversibile: metodi di sincronizzazione per AccessHandles

Il file system privato dell'origine consente di accedere a un tipo speciale di file altamente ottimizzato per le prestazioni, ad esempio offrendo accesso in scrittura ed esclusivo ai contenuti di un file. Gli sviluppatori possono accedere a questi file chiamando createSyncAccessHandle(), che è un metodo esposto agli oggetti FileSystemFileHandle. Questa chiamata genera un FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle è una primitiva di file che fornisce un accesso ad alte prestazioni ai file locali. Uno dei suoi principali casi d'uso sono le applicazioni che portano il codice C/C++ in Wasm; tuttavia, le chiamate asincrone non sono ancora completamente supportate su Wasm e l'utilizzo della libreria Asyncify come alternativa ha prestazioni notevolmente ridotte. La modalità sincrona di tutti i metodi dell'API FileSystemSyncAccessHandle corrisponde a quella prevista dall'applicazione sincrona basata su Wasm dell'API del file, simile a POSIX, rendendo l'API più ergonomica e aumentando al contempo le prestazioni sostanziali.

Novità

FileSystemSyncAccessHandle espone i seguenti metodi che in precedenza erano asincroni, ma che sono sincroni a partire da Chromium 108.

  • truncate(newSize): ridimensiona il file associato all'handle di accesso in modo che abbia una lunghezza di newSize byte. Se newSize è superiore alle dimensioni correnti del file, inserisce il file con byte nulli; in caso contrario, tronca il file.
  • getSize(): restituisce le dimensioni in byte del file associato all'handle di accesso.
  • flush(): verifica che i contenuti del file associato all'handle di accesso contengano tutte le modifiche apportate tramite write().
  • close(): svuota la maniglia di accesso e la chiude. La chiusura di un handle di accesso disabilita eventuali ulteriori operazioni sull'handle e rilascia il blocco sulla voce associata all'handle di accesso.
// 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();

Cosa devo fare?

Tieni presente che cambiare metodo da asincrono a sincrono è una modifica esposta al web con potenziale interruzione. Mentre l'utilizzo di await nei metodi sincroni è autonomo, qualsiasi utilizzo di Promise.then() non funzionerà. Se concateni una chiamata then() sul risultato di uno dei metodi precedentemente asincroni e ora sincroni, devi modificare il codice.

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