背景
Issue #46(大規模ペイロード向けWebSocketベースのIPCストリーミング)の分割Issue。
AS IS(現状)
fs_read_fileはファイル全体を一括でメモリに読み込み、base64エンコードして返す
- 10MBのファイルなら10MBの生データ + 約13MBのbase64文字列が一度にメモリに乗る
- WebView側でのbase64デコード + JSONパースがUIスレッドをブロック
fs_write_fileもbase64一括書き込みのみ
filesystem.rsに明示的なPhase 2B TODOコメントあり
関連コード
src-tauri/src/commands/filesystem.rs — fs_read_file(200行目)、fs_write_file(219行目)
src/vs/platform/files/common/fileService.ts — 本家の3段階読み込み戦略(参考)
TO BE(目標状態)
- チャンク単位のストリーミング読み込み(例: 256KBずつ)
- VS Codeの
IFileSystemProviderWithFileReadStreamCapabilityまたはFileOpenReadWriteCloseCapabilityを活用
- 本家と同様の3段階読み込み戦略(unbuffered / streamed / buffered)のサポート
- atomic write(一時ファイル→リネーム)の追加
- async/awaitによる暗黙的バックプレッシャー
想定アプローチ
- Rust側: チャンク読み込みコマンド(
fs_read_file_chunked)の追加
- TypeScript側:
ReadableStreamEvents<Uint8Array>を返すストリーミングプロバイダーの実装
- 既存の
readFileIntoStream()ヘルパーの再利用
本家(Electron版)の実装
3段階の読み込み戦略(自動選択)
Strategy A — Unbuffered Read(FileReadWriteのみ対応の場合)
provider.readFile(resource) → Uint8Array一括返し
- 小ファイル向け
Strategy B — Streamed Read(FileReadStream対応の場合)
provider.readFileStream(resource) → ReadableStreamEvents<Uint8Array>
- 256KBチャンクでストリーミング
readFileIntoStream()ヘルパー使用
Strategy C — Buffered Read(FileOpenReadWriteClose対応の場合)
provider.open() → provider.read(handle, pos, data, offset, length)ループ
- 同じく256KBチャンク
書き込み戦略
- Unbuffered:
provider.writeFile(resource, content) 一括
- Buffered:
provider.open() → provider.write()ループ(BUFFER_SIZE = 256KB)
- Atomic: 一時ファイルに書き込み →
rename()で置き換え(クラッシュ安全性)
バックプレッシャー
- async/awaitによる暗黙的制御: 各チャンクの書き込み完了をawaitしてから次を読む
関連コード(本家)
src/vs/platform/files/common/fileService.ts — 3戦略の自動選択ロジック
src/vs/platform/files/node/diskFileSystemProvider.ts — DiskFileSystemProvider実装
src/vs/platform/files/common/io.ts — readFileIntoStream() チャンク読み込みヘルパー
参考
背景
Issue #46(大規模ペイロード向けWebSocketベースのIPCストリーミング)の分割Issue。
AS IS(現状)
fs_read_fileはファイル全体を一括でメモリに読み込み、base64エンコードして返すfs_write_fileもbase64一括書き込みのみfilesystem.rsに明示的なPhase 2B TODOコメントあり関連コード
src-tauri/src/commands/filesystem.rs—fs_read_file(200行目)、fs_write_file(219行目)src/vs/platform/files/common/fileService.ts— 本家の3段階読み込み戦略(参考)TO BE(目標状態)
IFileSystemProviderWithFileReadStreamCapabilityまたはFileOpenReadWriteCloseCapabilityを活用想定アプローチ
fs_read_file_chunked)の追加ReadableStreamEvents<Uint8Array>を返すストリーミングプロバイダーの実装readFileIntoStream()ヘルパーの再利用本家(Electron版)の実装
3段階の読み込み戦略(自動選択)
Strategy A — Unbuffered Read(
FileReadWriteのみ対応の場合)provider.readFile(resource)→Uint8Array一括返しStrategy B — Streamed Read(
FileReadStream対応の場合)provider.readFileStream(resource)→ReadableStreamEvents<Uint8Array>readFileIntoStream()ヘルパー使用Strategy C — Buffered Read(
FileOpenReadWriteClose対応の場合)provider.open()→provider.read(handle, pos, data, offset, length)ループ書き込み戦略
provider.writeFile(resource, content)一括provider.open()→provider.write()ループ(BUFFER_SIZE = 256KB)rename()で置き換え(クラッシュ安全性)バックプレッシャー
関連コード(本家)
src/vs/platform/files/common/fileService.ts— 3戦略の自動選択ロジックsrc/vs/platform/files/node/diskFileSystemProvider.ts— DiskFileSystemProvider実装src/vs/platform/files/common/io.ts—readFileIntoStream()チャンク読み込みヘルパー参考
ws_relayパターン)ISocket,PersistentProtocol,IPCClient)filesystem.rs:198のPhase 2B TODOコメント