Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
The runtime test scans only one entry, so it cannot detect the old 32-entry cap or verify pagination and allocation at the configured batch size of 128.
1 open issue
What changed in this PR
This PR makes REFRESH page capacity configurable, reducing repeated cache-directory scans for large refreshes while preserving the default page size and request/response contract.
Changes:
- Adds
cache_purge_refresh_batchwith a default of 32 and a valid range of 1–256. - Sizes the scan’s entry storage and collection limit from the configured capacity.
- Documents the memory trade-off and adds configuration and runtime tests.
| File | Description |
|---|---|
t/purge_runtime.t |
Adds runtime coverage for a larger configured batch. |
t/config.t |
Tests accepted values, range rejection, and server-level configuration. |
ngx_cache_purge.h |
Defines the maximum batch size and configuration field. |
ngx_cache_purge_refresh.c |
Allocates and collects entries using the configured capacity. |
ngx_cache_purge_module.c |
Registers, initializes, inherits, and validates the directive. |
docs/DIRECTIVES.md |
Documents syntax, limits, and performance/memory trade-offs. |
Review effort: Balanced
A REFRESH page restarts its scan at the cache root, so a selector that spans many entries is delivered through several pages and the pending directories are walked again on every one. The page size was a fixed compile-time constant, which left large caches with no way to trade per-request memory for fewer repeated walks. Add cache_purge_refresh_batch (default 32, range 1..256) and allocate the page entries from the configured value. The array moves to the end of the scan structure so the extra capacity is part of the same allocation. The runtime coverage now warms three entries with a page size of two and checks that the first page is bounded and that the cursor returns the remainder, so a regression to the old fixed cap is visible.
a2e9778 to
f1487bc
Compare
|
Thanks — noted that the ASan/UBSan failure is the Vary reload flake fixed by 8849a4f (#79), not this change. I verified the suite locally under ASan/UBSan with that commit applied and it passes; this diff stays focused and CI can be re-run once #79 lands. Updated the runtime coverage per the review: it now warms three entries with a page size of two and checks that the first page is bounded by the configured value, that the cursor returns the remainder, and that no entry is reported twice. A regression to the previous fixed cap would now fail. |

Problem
A REFRESH page always restarts its scan at the cache root. The traversal state — open directory handles and the descent stack — cannot survive between requests, and
readdirhas no portable way to resume at an offset, so the cursor carries only a file hash and every page re-walks the pending directories.On caches with hundreds of thousands of entries and page counts in the low thousands, that repeated traversal dominates the cost of a whole-prefix refresh: the work grows with entries multiplied by pages instead of entries alone.
Change
Add
cache_purge_refresh_batch <number>(default 32, range 1..256) and size the page entries from it.The entry array moves to the end of the scan structure and the structure is allocated with room for the configured capacity, so a page still needs one allocation.
Compatibility
The directive is new; the default reproduces the previous page size, so existing configurations behave identically. The cursor format, the response schema and the request contract are unchanged.
Tests