feat(mem_wal): return the sealed generation from force_seal_active - #8051
Draft
hamersaw wants to merge 1 commit into
Draft
feat(mem_wal): return the sealed generation from force_seal_active#8051hamersaw wants to merge 1 commit into
hamersaw wants to merge 1 commit into
Conversation
`wait_for_flush_drain` loops until the frozen-watcher set is *empty*, re-collecting the set on each round — so it also waits on every memtable frozen while it waits, including ones the size/interval trigger and backpressure freeze concurrently. On a table under sustained write load that set may never empty, which makes any post-seal ack unbounded on exactly the workload that asks for one. The contract a caller actually needs is narrower: *everything written before my seal is in L0*. That is a predicate on one generation, not on the queue. So `force_seal_active` now returns the `SealedGeneration` it froze (`None` when the active memtable was empty, i.e. a no-op seal), and a caller can wait on the shard manifest's `current_generation` exceeding it — bounded by construction and unaffected by concurrent freezes. Also add `IndexStore::describe`, which reports the in-memory index set (kind + column) for diagnostics. An absent HNSW entry on a vector column is the whole explanation for a brute-force fresh-tier search, and there was no way to see it from outside. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
wait_for_flush_drainloops until the frozen-watcher set is empty, re-collecting the set on each round — so it also waits on every memtable frozen while it waits, including ones the size/interval trigger and backpressure freeze concurrently. On a table under sustained write load that set may never empty, which makes any post-seal ack unbounded on exactly the workload that asks for one.The contract a caller actually needs is narrower: everything written before my seal is in L0. That is a predicate on one generation, not on the queue.
What
force_seal_activenow returns theSealedGenerationit froze —Nonewhen the active memtable was empty (a no-op seal). A caller waits on the shard manifest'scurrent_generationexceeding it: bounded by construction, unaffected by concurrent freezes, and it makes the ack literally true instead of incidentally true.Also adds
IndexStore::describe, reporting the in-memory index set (kind + column) for diagnostics. An absent HNSW entry on a vector column is the whole explanation for a brute-force fresh-tier search, and there was no way to see it from outside the store.Compatibility
force_seal_active's return type changes fromResult<()>toResult<Option<SealedGeneration>>. Existing.await?;call sites compile unchanged (the value is simply dropped); only code that binds or asserts on the unit value needs touching. No format or on-disk change.Consumer
Sophon's WAL uses this to make
POST /v1/table/{name}/flushbounded — it currently callswait_for_flush_drainand inherits the unbounded-latency problem above.Notes for review
No new tests here: the change is a return value, and the bounded-wait semantics it enables are exercised on the consumer side (a test that seals, then keeps writing hard enough that the frozen set never empties, and asserts flush returns once its own generation lands — against
wait_for_flush_drainthat test hangs, which is the point of it). Happy to add a mem_wal test pinning that the returned generation matches the frozen memtable's if you want it covered here too.🤖 Generated with Claude Code