fix(files): keep large source previews responsive (#3665)
Large read-only files bypassed the editor's virtualization and eagerly mounted every highlighted token, which could stall the renderer for seconds and consume gigabytes of memory. Route source previews through bounded platform renderers and reject reads above their display budgets before accumulation.
This commit is contained in:
@@ -372,6 +372,30 @@ describe("WorkspaceFilesSession", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
test("rejects an over-budget file before opening a binary transfer", async () => {
|
||||
const cwd = makeDir("workspace-files-read-budget-");
|
||||
writeFileSync(join(cwd, "notes.txt"), "hello world");
|
||||
const { subsystem, emitted, binary } = makeSubsystem({ hasBinaryChannel: true });
|
||||
|
||||
await subsystem.handleFileExplorerRequest({
|
||||
type: "file_explorer_request",
|
||||
cwd,
|
||||
path: "notes.txt",
|
||||
mode: "file",
|
||||
requestId: "req-read-budget",
|
||||
acceptBinary: true,
|
||||
maxBytes: 5,
|
||||
});
|
||||
|
||||
expect(binary).toEqual([]);
|
||||
expect(emitted).toEqual([
|
||||
expect.objectContaining({
|
||||
type: "file_explorer_response",
|
||||
payload: expect.objectContaining({ error: "File is too large to display" }),
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
test("streams a real file larger than the socket limit as paced ordered chunks", async () => {
|
||||
const cwd = makeDir("workspace-files-large-binary-");
|
||||
const fileBytes = Buffer.alloc(8 * 1024 * 1024 + 123);
|
||||
|
||||
@@ -263,6 +263,12 @@ export class WorkspaceFilesSession {
|
||||
source,
|
||||
);
|
||||
} else {
|
||||
if (request.maxBytes) {
|
||||
const file = await getDownloadableFileInfo({ root: cwd, relativePath: requestedPath });
|
||||
if (file.size > request.maxBytes) {
|
||||
throw new Error("File is too large to display");
|
||||
}
|
||||
}
|
||||
if (request.acceptBinary && this.host.hasBinaryChannel()) {
|
||||
await streamExplorerFile({ root: cwd, relativePath: requestedPath }, async (file) => {
|
||||
await this.host.emitBinary(
|
||||
|
||||
Reference in New Issue
Block a user