Repository navigation
Conversation
Codecov Report❌ Patch coverage is
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
cabol
force-pushed
the
feat/drain-tuning-bench
branch
2 times, most recently
from
August 9, 2026 16:57
f0f5d07 to
6d1453e
Compare
Add a drain-tuning bench harness (mix bench) with recorded evidence in benchmarks/RESULTS.md; derive Caffeine-aligned per-buffer drain defaults in Maintenance.Supervisor (explicit drain_* opts still win); and fix the admission policy to run only under capacity pressure — window overflow now always promotes to probation, so writes are never discarded from an under-capacity cache.
cabol
force-pushed
the
feat/drain-tuning-bench
branch
from
August 9, 2026 17:16
6d1453e to
352bc0c
Compare
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
Two things ship here, one planned and one found along the way:
max_size, matching Caffeine'sevictFromWindow/evictFromMain. Same scenario after the fix: 500/500 resident, and 496/500 hot keys survive a 5,000-key flood.drain_*options, the maintenance supervisor derives Caffeine-aligned per-buffer thresholds; explicitdrain_*values still win, and unbounded caches are untouched.The defaults were chosen from evidence, not vibes: a new internal benchmark (
benchmarks/drain_tuning.exs) measures hit rate,max_sizeovershoot, post-burst policy lag, hot-set retention, and drain churn across configs — headline numbers below. The admission bug was itself caught by that harness (near-zero burst retention in every config flagged the discard path).Derived drain defaults
drain_thresholdmax(1, min(128, max_size / partitions))WRITE_BUFFER_MAX≈ 128/partition, capped bymax_size641All checked every
max(50, processing_interval / 10)ms (100ms at defaults).Headline evidence (18-core saturation harness,
max_size: 10_000, relative deltas are the signal):putips, Benchee guardrail)Grid isolation runs answered the plan's open questions: queue threshold 1 vs 50 is indistinguishable (the check interval is the rate limiter — picked 1 to kill the second timed stage), and dropping the read threshold costs 7pp burst retention plus 5× convergence lag for zero measurable hot-path savings, so it stays.
Design decisions
Maintenance.Supervisor.derive_drain_opts/2,@doc falsepublic) so bench configs can't drift from shipped defaults.Test plan
NEBULEX_PATH=... mix test), including new behavioral coverage: admission-only-over-capacity regression test, candidate skip paths (deleted / read-promoted mid-batch), admission→plain-LRU fallback within one resolution, derived defaults observed on running Tidefall partitions, explicit-override precedence,max_sizecap and check-interval floor.mix test.cigate passes (warnings-as-errors, format, credo strict, coverage, sobelow, dialyzer).20260809-112505-d59444f8): 5 validated findings applied infix(review); 1 rejected by independent validation (softening the single-writer assertions would mask real policy bugs).MIX_ENV=test mix run benchmarks/drain_tuning.exs(~8 min;BENCH_QUICK=1for a smoke run).Post-Deploy Monitoring & Validation
Library change, pre-release (
3.0.0-dev) — no production deployment. For early adopters validating an upgrade::ets.info(cache.data_table(), :size)) converging to ≤max_sizewithin ~2× the drain check interval after bursts; cache hit rate stable or improved; entries put on an under-capacity cache are immediately fetchable (the fixed bug).max_sizeunder normal (non-saturating) load;MatchErrorinNebulex.TinyLFU.Maintenance.admit_or_evict/3outside cache shutdown (at shutdown it's the known Tidefall race below); hit-rate regression vs. the previous interval-only build.Tidefall.Buffer.update_options/2, or pinned by setting explicitdrain_threshold/drain_check_intervalin:buffer_opts(explicit values override all derivation).Follow-ups
Tidefall.Buffer.Partition.terminate/2runs a final blocking drain while an in-flight runner task may still be processing, so twoprocess_maintenancecalls can overlap at cache shutdown and trip the single-writer assertions (noisyMatchErrorduring bench teardown; harmless for a dying cache). Fix belongs incabol/tidefall: await the runner task before the terminate drain.:tidefallback to a Hex release once one carrieskey_hasher: falsesupport (standing TODO from tidefall PR).:buffer_optsapplies onedrain_*pair to all three buffers; differentiated per-buffer overrides currently requireTidefall.Buffer.update_options/2(as the bench does). Worth a public per-buffer option surface if users ask.