test: add 24-hour ShardedPulseMap soak example - #14
Conversation
Add examples/soak_test.rs with configurable --duration (default 24h), 8 writers + 4 readers, TTL churn, periodic stats, sentinel integrity checks, monotonic eviction_count, capacity bounds, and Linux RSS growth detection. Short --duration values enable fast local/CI smoke runs. Fixes ddsha441981#8 Signed-off-by: Vedant Madane <6527493+VedantMadane@users.noreply.github.com>
|
Thanks for this — and sorry for the delay, the workflow run was stuck behind the fork-PR approval gate on my side, not on you. I ran it locally before merging and it works well. Two runs: I deliberately ran 190s so the 60-second stats path was exercised — a short run takes the One blocker
The Rustfmt job in CI will go red on this. Two small things1. The file has a UTF-8 BOM ( 2. The Design note — this one is on me, not youThe map saturates almost immediately and stays there: At ~15M ops/sec, a TTL of 10,000 insertion epochs is crossed in well under a millisecond. So the test hammers the eviction path hard — which is valuable — but the TTL-expiry / slot-reuse path that #8 was aiming at is effectively not exercised, and Also: you set Run |
|
Correcting my own "Design note" above — nothing here changes anything for you, all three items I asked for stand as written. This is only about my explanation of why the TTL path isn't covered, which was wrong. I said:
That's off by roughly 60x. Two mistakes: I used the total op rate, but the epoch counter only advances on insert, and in So ~60–76 ms, not sub-millisecond. The bigger error is what I concluded from it:
No parameter choice can fix it, because the path I was worried about does not exist on this type. // src/sync.rs:345
let (target_slot, is_eviction) = if let Some(free) = bucket.meta.find_free_slot() {whereas // src/raw.rs:178
let (target_slot, is_eviction) = if let Some(free) = self.find_free_or_expired(bucket_idx) {
I instrumented After the first 262,144 inserts fill every slot, 99.2% of inserts go through LFU/LRU eviction and So: your test does exercise the eviction path extremely hard, which is the valuable part, and my conclusion that the TTL-expiry path goes untested was right. But the reason is structural, not a parameter problem, and it is not something better params would repair. My follow-up will be about that asymmetry, not about tuning your numbers. One related thing worth flagging for anyone reading the output: The rest of my review is unchanged — |
Summary
Adds
examples/soak_test.rs— a long-running endurance test forShardedPulseMapunder sustained concurrent load.What it does
--duration <secs>(default 24 hours; short values for local/CI smoke)ShardedPulseMap<u64, u64>with 4096 buckets/shard andset_ttl(10_000)len() <= capacity(), monotoniceviction_count(), sentinel key integrity, Linux RSS growth ≤ 10%How to run
\\�ash
Full 24h
cargo run --release --example soak_test --features std
Quick smoke
cargo run --release --example soak_test --features std -- --duration 5
1-hour CI-style run
cargo run --release --example soak_test --features std -- --duration 3600
\\
Test plan
cargo build --example soak_test --features stdcargo run --example soak_test --features std -- --duration 3→ PASSED (~4.3M ops)Fixes #8