Nicht abwärtskompatible Änderung: Synchronisierungsmethoden für AccessHandles

Das private Ursprungsdateisystem bietet Zugriff auf eine spezielle Art von Datei, die stark für die Leistung optimiert ist, z. B. durch direkten und exklusiven Schreibzugriff auf den Inhalt einer Datei. Entwickler können auf solche Dateien zugreifen, indem sie createSyncAccessHandle() aufrufen. Das ist eine Methode, die für FileSystemFileHandle-Objekte freigegeben ist. Dieser Aufruf führt zu einem FileSystemSyncAccessHandle.

FileSystemSyncAccessHandle ist ein Dateiprimitiv, das einen leistungsstarken Zugriff auf lokale Dateien bietet. Einer der Hauptanwendungsfälle sind Anwendungen, bei denen C/C++-Code in Wasm portiert wird. Asynchrone Aufrufe werden in Wasm jedoch noch nicht vollständig unterstützt und die Verwendung der Asyncify-Bibliothek als Alternative hat die Leistung erheblich beeinträchtigt. Durch die Synchronisierung aller Methoden der FileSystemSyncAccessHandle entspricht sie der synchronen, POSIX-ähnlichen Datei-API, die von der Wasm-basierten Anwendung erwartet wird. Dadurch wird die API ergonomischer und bietet gleichzeitig erhebliche Leistungssteigerungen.

Das ist neu

FileSystemSyncAccessHandle stellt die folgenden Methoden bereit, die früher asynchron waren, aber seit Chromium 108 synchron sind.

  • truncate(newSize): Die Größe der Datei, die mit dem Zugriffs-Handle verknüpft ist, wird auf newSize Byte festgelegt. Wenn newSize größer als die aktuelle Dateigröße ist, wird die Datei mit Null-Byten aufgefüllt. Andernfalls wird sie abgeschnitten.
  • getSize(): Gibt die Größe der Datei zurück, die mit dem Zugriffs-Handle verknüpft ist, in Byte.
  • flush(): Sorgt dafür, dass der Inhalt der Datei, die mit dem Zugriffs-Handle verknüpft ist, alle über write() vorgenommenen Änderungen enthält.
  • close(): Der Zugriffs-Handle wird geleert und dann geschlossen. Wenn Sie einen Zugriffs-Handle schließen, werden alle weiteren Vorgänge darauf deaktiviert und die Sperre für den mit dem Zugriffs-Handle verknüpften Eintrag aufgehoben.
// 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();

Was muss ich tun?

Das Ändern der Methode von der asynchronen auf die synchrone Methode ist im Web sichtbar und kann zu Ausfällen führen. Die Verwendung von await in synchronen Methoden ist eine Nulloperation, jede Verwendung von Promise.then() funktioniert jedoch nicht. Wenn Sie einen then()-Aufruf mit dem Ergebnis einer der zuvor asynchronen und jetzt synchronen Methoden verketten, müssen Sie Ihren Code ändern.

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