fix(cache): cap wp-content/litespeed size with automatic oldest-first pruning (#777) - #1037
Open
faisalahammad wants to merge 1 commit into
Open
Conversation
faisalahammad
force-pushed
the
fix/777-max-cache-folder-size
branch
from
August 9, 2026 13:46
02b7fd6 to
e3911f5
Compare
Contributor
|
@faisalahammad there are some conflicts in this PR |
…peedtech#777) - New site-level setting 'Maximum Cache Folder Size' (MB) under Cache -> Purge - 15-min cron task (litespeed_task_folder_size) measures regenerable asset subdirs (css, js, ucss, ccss, optimax, lqip, avatar, localres) and prunes oldest-first down to a 90% hysteresis target - Default 0 keeps the cron as a no-op (BC). Setting reduced to 0 clears the schedule via the standard _conf_cron / Task::try_clean path - Multisite-safe: the recursive iterator walks all blog_id subfolders - Skips debug, cloud, auto-backup, crawler subdirs and root files (.litespeed_conf.dat, .htaccess, robots.txt). WebP/AVIF live in uploads/ and are not affected - Recreates .htaccess via File::ensure_static_protection() if the asset tree is fully cleared Fixes litespeedtech#777
faisalahammad
force-pushed
the
fix/777-max-cache-folder-size
branch
from
August 10, 2026 20:40
e3911f5 to
e792526
Compare
Contributor
Author
|
Rebased on latest dev and resolved readme.txt changelog conflict. New cache folder size bullet now sits under 8.0 section. Also fixed folder pruning review findings: verify deletion state and continue safely on iterator errors. Ready for re-review. |
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
New site-level setting Maximum Cache Folder Size (MB) under Cache -> Purge. When set > 0, a 15-min cron task measures the regenerable asset subdirs (css, js, ucss, ccss, optimax, lqip, avatar, localres) and prunes the oldest files until the tree is at 90% of the configured cap. Default 0 keeps the cron as a no-op, so existing installs are unaffected. Fixes #777.
Changes
src/folder.cls.php (new)
Before: No automated protection. wp-content/litespeed grows unbounded under aggressive bot traffic (WooCommerce filter URL combinations in the repro), eventually filling the disk.
After: Static cron callback that walks the asset subdirs with a RecursiveIteratorIterator, sums sizes, and when over budget deletes oldest files first via wp_delete_file, capped at 5000 files per run to avoid hogging a single tick.
Why: Issue #777 asks for a cap. The hot path (File::save) cannot run a recursive scan per write, so enforcement lives in a low-frequency cron. 90% hysteresis prevents thrash. 5000-file per-run cap resumes on the next tick instead of stalling cron.
src/task.cls.php
Before: No cron entry for folder size.
After: Adds 'litespeed_task_folder_size' to the triggers map, hooked to LiteSpeed\Folder::cron on the standard 15-min 'litespeed_filter' schedule. Task::try_clean clears the schedule when the setting goes back to 0.
Why: Reuses the existing 15-min cron infrastructure; the trigger map pattern is used by every other recurring task in the plugin.
src/base.cls.php
Before: No option id for the new setting.
After: Adds O_MISC_MAX_FOLDER_SIZE const, default 0 in the site-level options array, and the new id in _conf_cron check_ids so saves propagate to Task::try_clean.
Why: Setting registration chain (const -> default -> check_ids) is the established pattern in this file.
tpl/cache/settings-purge.tpl.php
Before: No UI for the new setting.
After: Adds an MB input row before the closing , mirroring the existing O_DEBUG_FILESIZE MB-input pattern. Includes description and _validate_ttl range guard (1-100000).
Why: Cache -> Purge tab is the right home for size-driven purge controls.
data/const.default.json
Before: No default for the new id.
After: Empty-string default so first-install reads the site-level default (0).
Why: Required by the Conf auto-sync flow.
src/lang.cls.php
Before: No title.
After: 'Maximum Cache Folder Size' label.
Why: Required by the title() helper.
autoload.php
Before: src/folder.cls.php not in the require list.
After: Added between file.cls.php and guest.cls.php, alphabetical order.
Why: autoload.php hardcodes the require_once list and the spl_autoload fallback only handles thirdparty/. Without this entry, the new class would not be loaded and the cron callback would fatal.
readme.txt
Before: No 8.0 changelog entry.
After: Bullet under '= 8.0 - Coming soon 2026 =' describing the limit and oldest-first pruning.
Why: Discoverability for the feature and a clear signal for the maintainer during release.
Testing
Test 1: setting UI shows up
Result: row renders, persists.
Test 2: disabled (default) is a no-op
Result: BC preserved.
Test 3: enabled triggers oldest-first prune
Result: works as expected.
Test 4: disable clears the schedule
Result: works as expected.
Test 5: bot-traffic simulation (original repro from #777)
Result: works as expected.
Test 6: phpcs
vendor/bin/phpcs --standard=phpcs.ruleset.xml --no-cache autoload.php src/folder.cls.php src/task.cls.php src/base.cls.php src/lang.cls.php tpl/cache/settings-purge.tpl.php
Result: 0 errors, 0 warnings.