fix: prevent blocking operations from freezing shard threads - #62
Merged
Conversation
adds a dedicated OS thread that receives large values and drops them off the hot path. this prevents expensive destructors (large lists, hashes, sorted sets) from blocking shard threads. - dropper.rs: bounded channel (4096 capacity) with try_send fallback - memory.rs: is_large_value() helper with 64-element threshold - strings always drop inline (Bytes is O(1) ref-counted)
integrates the background dropper into keyspace operations: - unlink(): like del but always defers the destructor - flush_async(): swaps entries map and returns old entries for deferred drop - del/try_evict/remove_if_expired: defer large value drops when handle is set - keys(): warn when scanning >10k keys (suggest SCAN instead)
- adds Unlink and FlushDbAsync shard request variants - spawn_shard now accepts an optional DropHandle for lazy free - engine creates a shared DropHandle and passes it to all shards - FlushDbAsync handled in the main loop: swaps entries, defers drop - Unlink maps to AofRecord::Del for replay (same semantics)
- Command::Unlink: parses like DEL, accepts one or more keys - Command::FlushDb: now has async_mode field, accepts optional ASYNC arg - parse_unlink mirrors parse_del exactly - parse_flushdb updated to accept optional ASYNC argument
- sharded mode: UNLINK routes through multi_key_bool like DEL - sharded mode: FLUSHDB broadcasts FlushDb or FlushDbAsync based on flag - concurrent mode: UNLINK handled same as DEL (DashMap has no blocking issue) - concurrent mode: FlushDb pattern updated for async_mode field
kacy
added a commit
that referenced
this pull request
Feb 11, 2026
* feat: add background value dropper for lazy free adds a dedicated OS thread that receives large values and drops them off the hot path. this prevents expensive destructors (large lists, hashes, sorted sets) from blocking shard threads. - dropper.rs: bounded channel (4096 capacity) with try_send fallback - memory.rs: is_large_value() helper with 64-element threshold - strings always drop inline (Bytes is O(1) ref-counted) * feat: add unlink and flush_async to keyspace with lazy free integrates the background dropper into keyspace operations: - unlink(): like del but always defers the destructor - flush_async(): swaps entries map and returns old entries for deferred drop - del/try_evict/remove_if_expired: defer large value drops when handle is set - keys(): warn when scanning >10k keys (suggest SCAN instead) * feat: wire up UNLINK and FLUSHDB ASYNC through shard and engine - adds Unlink and FlushDbAsync shard request variants - spawn_shard now accepts an optional DropHandle for lazy free - engine creates a shared DropHandle and passes it to all shards - FlushDbAsync handled in the main loop: swaps entries, defers drop - Unlink maps to AofRecord::Del for replay (same semantics) * feat: add UNLINK command parsing and FLUSHDB ASYNC support - Command::Unlink: parses like DEL, accepts one or more keys - Command::FlushDb: now has async_mode field, accepts optional ASYNC arg - parse_unlink mirrors parse_del exactly - parse_flushdb updated to accept optional ASYNC argument * feat: handle UNLINK and FLUSHDB ASYNC in connection handlers - sharded mode: UNLINK routes through multi_key_bool like DEL - sharded mode: FLUSHDB broadcasts FlushDb or FlushDbAsync based on flag - concurrent mode: UNLINK handled same as DEL (DashMap has no blocking issue) - concurrent mode: FlushDb pattern updated for async_mode field
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.
summary
ember-drop) for deferring expensive value deallocations off the shard hot pathUNLINKcommand — semantically identical toDELbut always defers the destructor to the background threadFLUSHDBto accept an optionalASYNCargument that swaps the entries map instantly and defers bulk deallocationDEL, eviction (try_evict), and lazy expiration (remove_if_expired) now automatically defer large value drops when the drop handle is present (values with >64 collection elements)KEYSis called on keyspaces with >10k keyswhat was tested
cargo test --workspace)dropper(defer small/large values, defer entries, empty entries skip)is_large_valuethreshold behavior (strings, lists, hashes, sets)UNLINK(single, multi, no args) andFLUSHDB ASYNC(with/without, case insensitive)cargo clippy --workspace— zero warningscargo fmt --check— cleandesign considerations
std::threadavoids this entirely.SyncSenderensures the shard never blocks waiting for the drop thread. if backpressure hits, we just drop inline — graceful degradation, not a hard failure.DELandUNLINKuse the samekeyspace.del()path.FLUSHDB ASYNCcallsclear()directly since there's no drop handle in concurrent mode.