open-brainy/tests/unit/brainy/open-path.test.ts

200 lines
7.7 KiB
TypeScript
Raw Normal View History

feat(open-path): init never gates on the embedding model; open goes concurrent; slow opens narrate A production restart storm measured 90,017ms for a single brain init vs 1,117ms quiet (~80x contention multiplier), traced to performInit() eagerly awaiting the process-global WASM embedding engine before the VFS root even existed. Every writer's open() queued on the one throttled model compile (90-140s on throttled CPUs). - VirtualFileSystem.doInitializeRoot() no longer embeds '/'. The root is system-tier plumbing nothing ever searches; when the default WASM engine is active it now gets an explicit all-zero placeholder vector (cosineDistance returns max distance for a zero vector, so it never ranks ahead of real content). deferEmbedding was considered and rejected: its landing path kicks the embed worker synchronously right after commit, which would still force the cold compile within milliseconds — just off the awaited path, not avoided. A registered native 'embeddings' provider (no cold-start cost, possibly a different dimension) still embeds the root for real, via the new Brainy.usesDefaultWasmEmbedder() seam. - performInit()'s eager-embedding step now only STARTS the WASM engine warm in the background instead of awaiting it inline. embed()/embeddingManager already serialize concurrent callers on one shared init promise, so the first real embed() converges correctly either way; a failed warm narrates loudly instead of surfacing as a silent latency spike or an unhandled rejection. eagerEmbeddings: false still means no warm at all. - FileSystemStorage.init() batches its ~8 independent bootstrap mkdirs (each creates its own full subtree via recursive:true, so none depend on the others existing) into one Promise.all. The restore-completion step and initializeCounts() stay strictly sequential — they have real order dependencies on rootDir and systemDir respectively. - performInit() now times five phases (storage init / generation-store open+fold / index init+gate / VFS bootstrap / embedding-warm-started) and logs one warning with the per-phase breakdown when total open exceeds 2000ms; silent otherwise.
2026-08-25 10:09:45 -07:00
/**
* OPEN-PATH tests: init() must never gate on the embedding model, the VFS
* root bootstrap must never touch the embedding engine, and a slow open
* must narrate its phases.
*
* Background: a production restart storm measured 90,017ms for a single
* brain init vs 1,117ms quiet an ~80x contention multiplier traced to
* every writer's init() eagerly awaiting the process-global WASM embedding
* engine before the VFS root even existed. See src/brainy.ts performInit()
* and src/vfs/VirtualFileSystem.ts doInitializeRoot().
*/
import { describe, it, expect, vi } from 'vitest'
import { Brainy } from '../../../src/brainy'
import { MemoryStorage } from '../../../src/storage/adapters/memoryStorage'
import { embeddingManager } from '../../../src/embeddings/EmbeddingManager'
import { createTestConfig } from '../../helpers/test-factory'
/**
* The four signals `isDeterministicEmbedMode()` checks (see
* src/embeddings/deterministicEmbedMode.ts). The global unit-test setup
* (tests/setup-unit.ts) sets some of these for the whole file/run in some
* vitest configurations; other configurations leave them unset and run the
* real WASM engine instead. The background-warm tests below need the
* "not unit-test mode" branch of performInit() to actually execute, so they
* save/clear/restore all four explicitly deterministic regardless of
* which config invoked this file, never relying on ambient state.
*/
function withRealEmbedderBranch<T>(fn: () => Promise<T>): Promise<T> {
const savedEnvDeterministic = process.env.BRAINY_DETERMINISTIC_EMBEDDINGS
const savedEnvUnitTest = process.env.BRAINY_UNIT_TEST
const g = globalThis as Record<string, unknown>
const savedGlobalDeterministic = g.__BRAINY_DETERMINISTIC_EMBED__
const savedGlobalUnitTest = g.__BRAINY_UNIT_TEST__
delete process.env.BRAINY_DETERMINISTIC_EMBEDDINGS
delete process.env.BRAINY_UNIT_TEST
delete g.__BRAINY_DETERMINISTIC_EMBED__
delete g.__BRAINY_UNIT_TEST__
const restore = () => {
if (savedEnvDeterministic !== undefined) process.env.BRAINY_DETERMINISTIC_EMBEDDINGS = savedEnvDeterministic
if (savedEnvUnitTest !== undefined) process.env.BRAINY_UNIT_TEST = savedEnvUnitTest
if (savedGlobalDeterministic !== undefined) g.__BRAINY_DETERMINISTIC_EMBED__ = savedGlobalDeterministic
if (savedGlobalUnitTest !== undefined) g.__BRAINY_UNIT_TEST__ = savedGlobalUnitTest
}
return fn().finally(restore)
}
/**
* A MemoryStorage whose init() takes an artificially long time a
* controllable fake seam (not a wall-clock race) that reliably pushes
* performInit()'s "storage-init" phase (and therefore the total open time)
* past the 2000ms narration threshold, without touching the filesystem or
* relying on real contention.
*/
class SlowMemoryStorage extends MemoryStorage {
override async init(): Promise<void> {
await new Promise((resolve) => setTimeout(resolve, 2200))
await super.init()
}
}
describe('OPEN-PATH: init() never gates on the embedding model', () => {
it('bootstrapping a fresh store never calls the embedding engine (VFS root add is engine-untouched)', async () => {
const embedSpy = vi.spyOn(embeddingManager, 'embed')
const brain = new Brainy(createTestConfig())
try {
await brain.init()
// The VFS root's add() must never have reached the embedding engine —
// it carries an explicit placeholder vector instead (see
// VirtualFileSystem.doInitializeRoot()).
expect(embedSpy).not.toHaveBeenCalled()
// Sanity: the VFS is genuinely usable afterwards.
const files = await brain.vfs.readdir('/')
expect(files).toEqual([])
} finally {
await brain.close()
embedSpy.mockRestore()
}
})
it('starts the embedding-engine warm in the BACKGROUND — init() resolves before the warm does', async () => {
await withRealEmbedderBranch(async () => {
const events: string[] = []
let releaseWarm!: () => void
const warmGate = new Promise<void>((resolve) => {
releaseWarm = resolve
})
const initSpy = vi.spyOn(embeddingManager, 'init').mockImplementation(async () => {
events.push('warm-start')
await warmGate
events.push('warm-resolve')
})
const brain = new Brainy(createTestConfig())
try {
await brain.init()
events.push('init-resolved')
// init() started the warm but returned WITHOUT waiting for it.
expect(initSpy).toHaveBeenCalledTimes(1)
expect(events).toEqual(['warm-start', 'init-resolved'])
// Now let the fake warm finish and confirm it lands strictly after.
releaseWarm()
await new Promise((resolve) => setTimeout(resolve, 0))
expect(events).toEqual(['warm-start', 'init-resolved', 'warm-resolve'])
} finally {
await brain.close()
initSpy.mockRestore()
}
})
})
it('narrates a background warm FAILURE loudly instead of losing it silently', async () => {
await withRealEmbedderBranch(async () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
const initSpy = vi
.spyOn(embeddingManager, 'init')
.mockRejectedValue(new Error('simulated cold-compile failure'))
const brain = new Brainy(createTestConfig())
try {
// init() itself must still resolve — a failed background warm is
// never fatal to open().
await expect(brain.init()).resolves.toBeUndefined()
// Give the background .catch() a microtask/macrotask to run.
await new Promise((resolve) => setTimeout(resolve, 0))
const failureLine = warnSpy.mock.calls
.map((args) => args.map(String).join(' '))
.find((line) => line.includes('background embedding-engine warm FAILED'))
expect(failureLine).toBeDefined()
expect(failureLine).toContain('simulated cold-compile failure')
} finally {
await brain.close()
initSpy.mockRestore()
warnSpy.mockRestore()
}
})
})
it('eagerEmbeddings: false starts no warm at all', async () => {
await withRealEmbedderBranch(async () => {
const initSpy = vi.spyOn(embeddingManager, 'init')
const brain = new Brainy({ ...createTestConfig(), eagerEmbeddings: false })
try {
await brain.init()
expect(initSpy).not.toHaveBeenCalled()
} finally {
await brain.close()
initSpy.mockRestore()
}
})
})
it('narrates a slow open with a per-phase ms breakdown once total time exceeds 2000ms', async () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
const brain = new Brainy({ ...createTestConfig(), storage: new SlowMemoryStorage() })
try {
await brain.init()
const slowOpenLine = warnSpy.mock.calls
.map((args) => args.map(String).join(' '))
.find((line) => line.includes('[Brainy] slow open:'))
expect(slowOpenLine).toBeDefined()
expect(slowOpenLine).toContain('storage-init=')
expect(slowOpenLine).toContain('generation-store-open-fold=')
expect(slowOpenLine).toContain('index-init-gate=')
expect(slowOpenLine).toContain('vfs-bootstrap=')
expect(slowOpenLine).toContain('embedding-warm-started=')
} finally {
await brain.close()
warnSpy.mockRestore()
}
}, 20000)
it('stays silent about phase timing when open is fast (under 2000ms)', async () => {
const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
const brain = new Brainy(createTestConfig())
try {
await brain.init()
const slowOpenLine = warnSpy.mock.calls
.map((args) => args.map(String).join(' '))
.find((line) => line.includes('[Brainy] slow open:'))
expect(slowOpenLine).toBeUndefined()
} finally {
await brain.close()
warnSpy.mockRestore()
}
})
})