브레이킹 체인지: AccessHandles의 동기화 메서드

원본 비공개 파일 시스템은 파일 콘텐츠에 대한 인플레이스 및 독점 쓰기 액세스 권한을 제공하는 등의 방법으로 성능을 위해 고도로 최적화된 특별한 종류의 파일에 대한 액세스를 제공합니다. 개발자는 FileSystemFileHandle 객체에 노출된 메서드인 createSyncAccessHandle()를 호출하여 이러한 파일에 액세스할 수 있습니다. 이 호출의 결과는 FileSystemSyncAccessHandle입니다.

FileSystemSyncAccessHandle는 로컬 파일에 대한 성능이 우수한 액세스를 제공하는 파일 프리미티브입니다. 주요 사용 사례 중 하나는 C/C++ 코드를 Wasm으로 포팅하는 애플리케이션입니다. 그러나 비동기 호출은 아직 Wasm에서 완전히 지원되지 않으며 Asyncify 라이브러리를 대안으로 사용하면 성능이 크게 저하되었습니다. FileSystemSyncAccessHandle의 모든 메서드를 동기화하여 동기식 POSIX 유형의 파일 API Wasm 기반 애플리케이션이 기대하는 대로 동기화합니다. 이를 통해 API의 사용성을 개선하고 상당한 성능 향상을 가져옵니다.

새로운 기능

FileSystemSyncAccessHandle는 비동기식이지만 Chromium 108부터 동기식인 다음 메서드를 노출합니다.

  • truncate(newSize): 액세스 핸들과 연결된 파일의 크기를 newSize바이트로 조절합니다. newSize가 현재 파일 크기보다 큰 경우 파일을 null 바이트로 채우고, 그렇지 않으면 파일을 자릅니다.
  • 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 */