mirror of
https://github.com/stablyai/orca.git
synced 2026-09-22 08:02:28 +00:00
feat(ai-vault-search): expose the index handle a composed reader queries
PR 4's engine reads the index this store owns. One getter lets it compose over the store's handle instead of opening a second connection to the same file, and it carries the two rules this PR measured: never hold a read transaction across an await, and no `.iterate()` outliving its statement. Either pins a read snapshot, and a checkpoint cannot pass one, so the WAL grows without bound for as long as it is held (10 MB to 266 MB on the write benchmark).
This commit is contained in:
@@ -491,6 +491,14 @@ it('writes nothing for an incomplete read and owes the file a whole re-read', ()
|
||||
expect(errors).toEqual([])
|
||||
})
|
||||
|
||||
it('exposes the handle a composed reader queries through', () => {
|
||||
replayTranscriptRead({ messages: userMessages('composedreader', 3) })
|
||||
|
||||
// PR 4's engine reads through this rather than opening a second connection,
|
||||
// so it sees a write the moment the transaction commits.
|
||||
expect(store.connection.prepare('SELECT count(*) AS n FROM messages').get()).toEqual({ n: 3 })
|
||||
})
|
||||
|
||||
it('closes twice without turning the second call into an error', () => {
|
||||
store.close()
|
||||
// node:sqlite throws ERR_INVALID_STATE on a second close of one handle, and a
|
||||
|
||||
@@ -45,6 +45,21 @@ export class SessionSearchStore {
|
||||
this.writer = new SessionSearchIndexWriter(this.db)
|
||||
}
|
||||
|
||||
/**
|
||||
* The index handle, for a reader composed over this store (PR 4's engine).
|
||||
*
|
||||
* Two rules come with it, both measured in this PR. **Never hold a read
|
||||
* transaction across an `await`**: a checkpoint cannot pass an open read
|
||||
* snapshot, so a paginated read that opened `BEGIN` and yielded between pages
|
||||
* takes the WAL from 10 MB to 266 MB and it does not come back. And **no
|
||||
* `.iterate()` that outlives its statement**, which is the same pin by
|
||||
* another name. Every retrieval a single synchronous statement is the whole
|
||||
* contract.
|
||||
*/
|
||||
get connection(): SyncDatabase {
|
||||
return this.db
|
||||
}
|
||||
|
||||
setAcceptingWrites(accept: boolean): void {
|
||||
this.acceptingWrites = accept
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user