Fix RocksDB @expiresAt eviction sweeps - #2155
Conversation
There was a problem hiding this comment.
Code Review
This pull request optimizes the record expiration sweep by introducing RocksDB index value enumeration and batching the eviction process in groups of 100 records. It also adds a fallback mechanism to clean up dangling index entries when a record is already gone. The review feedback correctly identifies a redundant database read in this fallback path when primaryStore.ifVersion is undefined, suggesting a simplification to avoid unnecessary I/O overhead.
|
Reviewed; no blockers found. Suggestions (non-blocking)
|
9426905 to
9f7e742
Compare
Patch cherry-pick: cancelledThe |
9f7e742 to
c54d4b6
Compare
|
Patch? Really? |
|
Good catch. I removed the Update: at Kyle’s request, I rewrote the five PR commits so both author and committer use Comment generated by kAIle (GPT-5.6) |
c54d4b6 to
409138c
Compare
cb1kenobi
left a comment
There was a problem hiding this comment.
About a year ago, I tried to add support for getValues() and we ended up abandoning it in rocksdb-js on June 25, 2025 due to "key sort order" challenges.
I created an IndexStore that extends a Store and would handle the encoding of the keys: https://github.com/HarperFast/rocksdb-js/blob/index-store/src/index-store.ts. I don't remember the specifics, but I remember naively creating an array as the key won't work. If you wanted "hello", it gave you "hello world" too. I tried adding markers around the values, but even those could cause matches. I don't think I tested fixed width keys, but that might yield some success.
We ended up dropping dupSort, getValues(), and getValuesCount() from rocksdb-js.
It's a year later now, the dust has settled, things have stabilized, LLMs have gotten smarter, and maybe this is solvable. I think the next step for this PR is to add way more tests, specifically with similar values.
kriszyp
left a comment
There was a problem hiding this comment.
I guess additional concerns I have: I think http://github.com/HarperFast/rocksdb-js/issues/312 is the real solution here. This is would be kind of a temporary solution for... who? I thought the only place we had ever used this was for the EKV project that didn't go through and this received little attention after that. But sure, I guess there is an immediate need for this, we can keep going with this. I think the ticket is marked P1. We haven't been automatically prioritizing P1 tickets into 5.2 patch (while we still have open P0s, or at least P1s with active customer connections).
🤖 Reviewed with Claude
|
All requested review items are addressed in the latest push:
This remains a main/v5.2+ fix, not a v5.1 patch. The immediate consumer is the engineering-metrics RocksDB deployment using Local verification is green, including 37 focused tests. All nine review threads are resolved; no reviewer was assigned. Comment generated by kAIle (GPT-5.6) |
…ation-eviction # Conflicts: # resources/blob.ts
| const { setMainIsWorker } = require('#js/server/threads/manageThreads'); | ||
| const { Transaction: RocksTransaction } = require('@harperfast/rocksdb-js'); | ||
| const { asBinary } = require('lmdb'); | ||
| const sinon = require('sinon'); |
There was a problem hiding this comment.
Suggestion (non-blocking): This PR introduces sinon into unitTests/resources/expiresAtAttribute.test.js and unitTests/resources/closeLoadedDatabases.test.js (14+ new sinon.stub/sinon.spy call sites) — both previously sinon-free. AGENTS.md is explicit that unitTests/resources/* is the target shape that should avoid this ("do not add new uses of sinon or rewire... If you can't write a test without stubbing, comment on the issue describing what's missing and stop"). Several of these stub globals (global.setInterval/setTimeout) or prototypes (RocksTransaction.prototype.commit, Table.evict) rather than exercising the code through an exported hook — kriszyp already flagged one of these exact patterns as fragile in an earlier review round. Consider exporting a direct test hook for the sweep/eviction body (e.g. a runRecordExpirationEviction-once function) instead of monkey-patching globals/prototypes, per the AGENTS.md guidance.
Summary
@expiresAtsweeps workFixes #1481. The broader native index-store work remains tracked in HarperFast/rocksdb-js#312.
Rollout behavior
This intentionally activates physical reclamation for expired RocksDB rows that reads already treat as absent. The prior Rocks sweep was effectively inert, so an upgraded node may have an existing backlog. The sweep drains that backlog without an audit or replication event, matching eviction semantics; it yields every 10 candidates and limits transaction commits to four in flight, but it does not impose the previously reviewed 10k/min ceiling. This behavior change needs explicit release-note and human rollout sign-off.
Verification
npm run buildnpm run typechecknpm run test:typesnpm run lint:requirednpm run format:checkComment generated by kAIle (GPT-5.6)