mirror of
https://github.com/stablyai/orca.git
synced 2026-10-30 16:47:34 +00:00
perf(ai-vault): share concurrent Codex title-index reads (#28497)
* perf(ai-vault): share concurrent Codex title-index reads * bench(ai-vault): reproduce Codex title-index reads * chore: drop one-off benchmark script; order imports
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { basename, dirname, join } from 'node:path'
|
||||
import { createInterface } from 'node:readline'
|
||||
import { InFlightPromiseDedupe, stableInFlightKey } from '../../shared/in-flight-promise-dedupe'
|
||||
import { openTranscriptReadStream, wslGatedStat } from '../native-chat/wsl-transcript-fs-access'
|
||||
import { WslTranscriptFsError } from '../native-chat/wsl-transcript-fs-gate'
|
||||
import { extractString, normalizeTitleText, parseJsonObject } from './session-scanner-values'
|
||||
@@ -18,9 +19,14 @@ type CodexSessionIndexTitleCacheEntry = {
|
||||
}
|
||||
|
||||
const codexSessionIndexTitleCache = new Map<string, Promise<CodexSessionIndexTitleCacheEntry>>()
|
||||
const inFlightTitleReads = new InFlightPromiseDedupe<Map<string, string>>(
|
||||
0,
|
||||
CODEX_SESSION_INDEX_TITLE_CACHE_MAX
|
||||
)
|
||||
|
||||
export function resetCodexSessionIndexTitleCacheForTests(): void {
|
||||
codexSessionIndexTitleCache.clear()
|
||||
inFlightTitleReads.clear()
|
||||
}
|
||||
|
||||
export function _getCodexSessionIndexTitleCacheSizeForTest(): number {
|
||||
@@ -88,6 +94,22 @@ async function readCodexSessionIndexTitles(codexHome: string): Promise<Map<strin
|
||||
return cachedTitles
|
||||
}
|
||||
|
||||
// A shared WSL stat resumes cache misses together; share the reload before opening the index.
|
||||
return inFlightTitleReads.run(stableInFlightKey([codexHome, signature]), () =>
|
||||
loadCodexSessionIndexTitles(codexHome, indexPath, signature)
|
||||
)
|
||||
}
|
||||
|
||||
async function loadCodexSessionIndexTitles(
|
||||
codexHome: string,
|
||||
indexPath: string,
|
||||
signature: string
|
||||
): Promise<Map<string, string>> {
|
||||
const cachedTitles = await readCachedCodexSessionIndexTitles(codexHome, signature)
|
||||
if (cachedTitles) {
|
||||
return cachedTitles
|
||||
}
|
||||
|
||||
const pending = readCodexSessionIndexTitlesFromDisk(indexPath).then(({ titles, refused }) => {
|
||||
// Why: a gate refusal is a stalled distro, not a title-less index — caching
|
||||
// it would pin "no titles" until the index's size or mtime changes.
|
||||
|
||||
@@ -86,6 +86,87 @@ afterEach(async () => {
|
||||
})
|
||||
|
||||
describe('memoized WSL session indexes under a stalled mount', () => {
|
||||
it('shares one cold Codex index read across a concurrent parser batch', async () => {
|
||||
const handles: ReturnType<typeof servingHandle>[] = []
|
||||
mocks.open.mockImplementation(async () => {
|
||||
const handle = servingHandle(
|
||||
`${JSON.stringify({ id: SESSION_ID, thread_name: 'Shared title' })}\n`
|
||||
)
|
||||
handles.push(handle)
|
||||
return handle
|
||||
})
|
||||
|
||||
const titles = await Promise.all(
|
||||
Array.from({ length: 8 }, () =>
|
||||
readCodexSessionIndexTitle(CODEX_SESSION_FILE, CODEX_HOME, SESSION_ID)
|
||||
)
|
||||
)
|
||||
|
||||
expect(titles).toEqual(Array.from({ length: 8 }, () => 'Shared title'))
|
||||
expect(mocks.stat).toHaveBeenCalledTimes(1)
|
||||
expect(mocks.open).toHaveBeenCalledTimes(1)
|
||||
expect(handles).toHaveLength(1)
|
||||
expect(handles[0].close).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
|
||||
it('keeps concurrent Codex homes separate even when their file signatures match', async () => {
|
||||
const otherHome = `${CODEX_HOME}-other`
|
||||
mocks.open.mockImplementation(async (path: string) =>
|
||||
servingHandle(
|
||||
`${JSON.stringify({
|
||||
id: SESSION_ID,
|
||||
thread_name: path.includes('-other') ? 'Other home' : 'First home'
|
||||
})}\n`
|
||||
)
|
||||
)
|
||||
|
||||
const titles = await Promise.all(
|
||||
[CODEX_HOME, otherHome].flatMap((home) =>
|
||||
Array.from({ length: 8 }, () =>
|
||||
readCodexSessionIndexTitle(CODEX_SESSION_FILE, home, SESSION_ID)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
expect(titles).toEqual([
|
||||
...Array.from({ length: 8 }, () => 'First home'),
|
||||
...Array.from({ length: 8 }, () => 'Other home')
|
||||
])
|
||||
expect(mocks.open).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('shares one changed Codex index read and preserves later title updates', async () => {
|
||||
mocks.open.mockImplementation(async () =>
|
||||
servingHandle(`${JSON.stringify({ id: SESSION_ID, thread_name: 'Original title' })}\n`)
|
||||
)
|
||||
expect(await readCodexSessionIndexTitle(CODEX_SESSION_FILE, CODEX_HOME, SESSION_ID)).toBe(
|
||||
'Original title'
|
||||
)
|
||||
mocks.open.mockClear()
|
||||
mocks.stat.mockResolvedValue({ ...INDEX_STATS, mtimeMs: 8 })
|
||||
mocks.open.mockImplementation(async () =>
|
||||
servingHandle(`${JSON.stringify({ id: SESSION_ID, thread_name: 'Updated title' })}\n`)
|
||||
)
|
||||
|
||||
const titles = await Promise.all(
|
||||
Array.from({ length: 8 }, () =>
|
||||
readCodexSessionIndexTitle(CODEX_SESSION_FILE, CODEX_HOME, SESSION_ID)
|
||||
)
|
||||
)
|
||||
|
||||
expect(titles).toEqual(Array.from({ length: 8 }, () => 'Updated title'))
|
||||
expect(mocks.open).toHaveBeenCalledTimes(1)
|
||||
|
||||
mocks.stat.mockResolvedValue({ ...INDEX_STATS, mtimeMs: 9 })
|
||||
mocks.open.mockImplementation(async () =>
|
||||
servingHandle(`${JSON.stringify({ id: SESSION_ID, thread_name: 'Latest title' })}\n`)
|
||||
)
|
||||
expect(await readCodexSessionIndexTitle(CODEX_SESSION_FILE, CODEX_HOME, SESSION_ID)).toBe(
|
||||
'Latest title'
|
||||
)
|
||||
expect(mocks.open).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('evicts the Codex title index instead of pinning "no titles"', async () => {
|
||||
mocks.open.mockResolvedValue({ read: vi.fn(stalls), close: vi.fn(async () => {}) })
|
||||
const refused = readCodexSessionIndexTitle(CODEX_SESSION_FILE, CODEX_HOME, SESSION_ID)
|
||||
|
||||
Reference in New Issue
Block a user