Skip to content

Query: prevent invalidated query caches from accumulating in 3.0. - #255

Merged
JJJ merged 1 commit into
release/3.0.xfrom
fix/253-cache-retention-3.0
Sep 9, 2026
Merged

Query: prevent invalidated query caches from accumulating in 3.0.#255
JJJ merged 1 commit into
release/3.0.xfrom
fix/253-cache-retention-3.0

Conversation

@JJJ

@JJJ JJJ commented Sep 9, 2026

Copy link
Copy Markdown
Collaborator

Port the 2.0.3 query-result cache fix to the released 3.0 line. Repeated invalidations now replace the result at one stable key instead of accumulating generation-suffixed keys. Each entry carries the generation captured before its database read; entries with missing or stale generations are replaced.

Robin's unset-value cache-key correction already exists in 3.0.0. Remove the now-unused private get_cache_key() parameter, as noted in the review of #254. No public API or runtime requirement changes.

Validation:

  • PHP 8.1 and 8.2, WordPress 6.7.7, MariaDB 10.2: 617 tests / 1,209 assertions passed on each PHP version.
  • Redis 7, using an external test-only adapter: 9 cache tests / 43 assertions passed.
  • All three new regression methods fail against unpatched 3.0.0 (two failures and one missing-generation error).
  • Composer validation, PHPStan, PHPCS, and diff checks passed.

Existing orphaned entries are not removed, and distinct query entries do not gain an expiration policy. The development-branch up-port is separate.

Props @hellofromahmed for reporting #253 and @robincornett for the existing sentinel correction (#185).

See #253, #254, #185.

Port the 2.0.3 result-cache fix to the 3.0 maintenance line. Store the
cache generation with each result, validate it before reuse, and replace
stale results at the same key. Capture the generation before reading the
database. Remove the unused private cache-key parameter.

Add regression coverage for repeated mutations, missing and stale
generations, empty results, and invalidation during a database read.

Props hellofromahmed for reporting the persistent-cache growth.
Props robincornett for the existing unset-value cache-key correction.
See #253, #254, #185.
Copilot AI lite review requested due to automatic review settings September 9, 2026 03:22
@JJJ
JJJ merged commit 2e4a391 into release/3.0.x Sep 9, 2026
5 checks passed
@JJJ
JJJ deleted the fix/253-cache-retention-3.0 branch September 9, 2026 03:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The newly added tests invoke private methods via ReflectionMethod without the existing PHP-version guard needed for compatibility with PHP < 8.1, which can break the test suite on supported older runtimes.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Ports the 2.0.3 query-result cache fix to the 3.0 release line so repeated invalidations no longer accumulate generation-suffixed cache keys; instead, results are stored under a stable key and validated against a captured cache-generation value.

Changes:

  • Make query-result cache keys generation-independent and store last_changed inside the cached payload for stale-entry detection.
  • Replace cache writes with cache_set() so stale/missing-generation entries can be overwritten at the stable key.
  • Add regression tests covering stable-key replacement, stale/missing generations, and “generation captured before DB read”.
File summaries
File Description
tests/Database/Query/QueryCacheTest.php Adds regression coverage for stable cache keys and generation-aware cached payloads.
src/Database/Kern/Query.php Implements stable cache keys and generation validation/replacement in query-result caching.
Review details

Suppressed comments (2)

tests/Database/Query/QueryCacheTest.php:302

  • This test invokes private get_cache_key()/get_cache_group() via ReflectionMethod without the PHP_VERSION_ID < 80100 setAccessible(true) guard used elsewhere in this file, which will break the suite on PHP < 8.1.
		$query   = new TestQuery( $args );
		$get_key = new \ReflectionMethod( TestQuery::class, 'get_cache_key' );
		$group   = ( new \ReflectionMethod( TestQuery::class, 'get_cache_group' ) )->invoke( self::$query );
		$key     = $get_key->invoke( $query );

tests/Database/Query/QueryCacheTest.php:337

  • Same reflection-access issue here: for PHP < 8.1, invoking private methods via ReflectionMethod requires setAccessible(true) (as done in the earlier tests), otherwise the test will fail.
		$query   = new TestQuery( $args );
		$get_key = new \ReflectionMethod( TestQuery::class, 'get_cache_key' );
		$group   = ( new \ReflectionMethod( TestQuery::class, 'get_cache_group' ) )->invoke( self::$query );
		$key     = $get_key->invoke( $query );
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +260 to +262
$get_key = new \ReflectionMethod( TestQuery::class, 'get_cache_key' );
$group = ( new \ReflectionMethod( TestQuery::class, 'get_cache_group' ) )->invoke( self::$query );
$query = new TestQuery( $args );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants