Skip to content

Commit 12e9d28

Browse files
committed
perf(server): resolve a folder's symlinks in bounded batches
1 parent a9fdedd commit 12e9d28

1 file changed

Lines changed: 20 additions & 8 deletions

File tree

‎apps/server/src/workspace/WorkspaceEntries.ts‎

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ export class WorkspaceEntries extends Context.Service<
109109
/** Paths sent to one `git check-ignore` call when labelling a folder's children. */
110110
const IGNORE_CHECK_CHUNK_SIZE = 1000;
111111

112+
/** Children classified at once when listing a folder; each symlink costs a realpath and a stat. */
113+
const SYMLINK_RESOLVE_BATCH_SIZE = 64;
114+
112115
const resolveBrowseTarget = Effect.fn("WorkspaceEntries.resolveBrowseTarget")(function* (
113116
input: FilesystemBrowseInput,
114117
path: Path.Path,
@@ -354,14 +357,23 @@ export const make = Effect.gen(function* () {
354357
? undefined
355358
: "directory";
356359
};
357-
const kinds = await Promise.all(
358-
children.map(async (child): Promise<ProjectEntry["kind"] | undefined> => {
359-
if (child.name === ".git") return undefined;
360-
if (child.isDirectory()) return "directory";
361-
if (child.isFile()) return "file";
362-
return child.isSymbolicLink() ? resolveSymlinkKind(child.name) : undefined;
363-
}),
364-
);
360+
// A pnpm `node_modules` holds a link per package. Resolving them in batches keeps
361+
// a large folder from queueing thousands of calls ahead of other filesystem work.
362+
const kinds: Array<ProjectEntry["kind"] | undefined> = [];
363+
for (let offset = 0; offset < children.length; offset += SYMLINK_RESOLVE_BATCH_SIZE) {
364+
kinds.push(
365+
...(await Promise.all(
366+
children
367+
.slice(offset, offset + SYMLINK_RESOLVE_BATCH_SIZE)
368+
.map(async (child): Promise<ProjectEntry["kind"] | undefined> => {
369+
if (child.name === ".git") return undefined;
370+
if (child.isDirectory()) return "directory";
371+
if (child.isFile()) return "file";
372+
return child.isSymbolicLink() ? resolveSymlinkKind(child.name) : undefined;
373+
}),
374+
)),
375+
);
376+
}
365377
return {
366378
entries: children.flatMap((child, index): ProjectEntry[] => {
367379
const kind = kinds[index];

0 commit comments

Comments
 (0)