브레이킹 체인지: 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 */