perf(recent-projects): stream codex session discovery

This commit is contained in:
777genius 2026-05-26 16:08:25 +03:00
parent 031e5eda2f
commit 72633daa6e
2 changed files with 33 additions and 13 deletions

View file

@ -345,18 +345,30 @@ async function listRecentJsonlFiles(
if (!hasBudget()) { if (!hasBudget()) {
return; return;
} }
let entries; let directoryHandle;
try { try {
entries = await fs.readdir(directory, { withFileTypes: true, encoding: 'utf8' }); directoryHandle = await fs.opendir(directory, { encoding: 'utf8' });
} catch { } catch {
return; return;
} }
directoriesVisited += 1; directoriesVisited += 1;
const filePaths: string[] = []; const fileBatch: string[] = [];
const childDirectories: string[] = []; const childDirectories: string[] = [];
const flushFileBatch = async (): Promise<void> => {
if (!fileBatch.length) {
return;
}
const batch = fileBatch.splice(0, fileBatch.length);
await collectFileStats(batch);
};
try {
for await (const entry of directoryHandle) {
if (!hasBudget()) {
return;
}
for (const entry of entries) {
const entryPath = path.join(directory, entry.name); const entryPath = path.join(directory, entry.name);
if (entry.isDirectory()) { if (entry.isDirectory()) {
if (depth < maxDepth) { if (depth < maxDepth) {
@ -366,11 +378,17 @@ async function listRecentJsonlFiles(
} }
if (entry.isFile() && entry.name.endsWith('.jsonl')) { if (entry.isFile() && entry.name.endsWith('.jsonl')) {
filePaths.push(entryPath); fileBatch.push(entryPath);
if (fileBatch.length >= CODEX_SESSION_FILE_DISCOVERY_STAT_BATCH_SIZE) {
await flushFileBatch();
} }
} }
}
} catch {
return;
}
await collectFileStats(filePaths); await flushFileBatch();
for (const childDirectory of childDirectories) { for (const childDirectory of childDirectories) {
if (!hasBudget()) { if (!hasBudget()) {

View file

@ -742,6 +742,7 @@ describe('CodexSessionFileRecentProjectsSourceAdapter', () => {
) )
) )
); );
const readdirSpy = vi.spyOn(fs, 'readdir');
const adapter = new CodexSessionFileRecentProjectsSourceAdapter({ const adapter = new CodexSessionFileRecentProjectsSourceAdapter({
getActiveContext: () => ({ type: 'local', id: 'local-1' }) as never, getActiveContext: () => ({ type: 'local', id: 'local-1' }) as never,
@ -767,6 +768,7 @@ describe('CodexSessionFileRecentProjectsSourceAdapter', () => {
skippedUncached: 340, skippedUncached: 340,
}) })
); );
expect(readdirSpy).not.toHaveBeenCalled();
}); });
it('skips non-interactive and ephemeral sessions', async () => { it('skips non-interactive and ephemeral sessions', async () => {