GT Performance 1.0.0-beta-5
Changed
- Moved the everyday operations — purge GT cache, Cloudflare sync, and the two drop-in installers — from the Tools tab onto the dashboard. Purging after a content change no longer takes a detour, and the installers are visible during setup, which is exactly when they are needed. Tools keeps runtime drop-in status and database maintenance. Each operation now remembers which screen it was run from and returns there instead of always landing on Tools.
Fixed
- Stale pages are now rebuilt instead of being served indefinitely. Nothing regenerated an entry between
fresh_ttlandstale_ttl: the drop-in served the stale body and exited, and a preload request received that same stale body, so the only escape from the stale window wasstale_untilexpiring. A live site measured 1,011 of 1,023 cached pages stale, median age 14.3 hours. The queue now sweeps for stale entries on each scheduled run and enqueues preloads, and the drop-in treats a stale entry as a miss when the request carriesX-GT-Preload, so those preloads actually rebuild the page. Batches are capped at 5 per run — matching what the queue drains per tick, sinceenqueue()does not deduplicate — and skipped entirely while a preload backlog is still pending, so the job table cannot grow faster than it clears. The cap is filterable viagt_performance_revalidate_batch. - Fixed the Redis object cache silently flushing nothing.
flush()andflush_group()build aSCAN MATCHpattern from the key prefix, which defaults toWP_CACHE_KEY_SALT— a random string that regularly contains[,?, or*, all glob metacharacters. An unclosed[makes the pattern match zero keys, so both calls deleted nothing and still returnedtrue; a live site'swp cache flushreported success while the entries stayed in Redis. Literal prefixes are now escaped before use in a pattern. - Re-arm the queue cron when the scheduled event is missing.
Activatorschedules it once at activation and nothing restored it if it was later lost, which stops the queue permanently: purges never preload, warms never run, stale pages are never rebuilt. A production site was found with the event absent and jobs pending for seven days. - Invalidate a rebuilt page's metadata in the opcode cache. The drop-in reads metadata with
include, so a refreshed entry could be read back with its previous timestamps until opcache revalidated — and never, on a host runningopcache.validate_timestamps=0. - Wrapped the Redis object cache's
SCANloop in the same error handling every other Redis call already had. It was the one unguarded call in the drop-in, so a mid-scan disconnect raised an uncaughtRedisExceptionthrough group flushes and took the request down with a fatal instead of degrading to a cache miss. The loop is now bounded as well, so a driver that returns without advancing the cursor cannot spin.