fix(2meet-data-optimizer-hivepress-addon): with an object cache, keep HivePress transients out of wp_options entirely
Tests / PHP Lint (pull_request) Successful in 10s
Tests / Unit Tests (pull_request) Successful in 1m2s
Tests / Integration Tests (pull_request) Successful in 1m53s

- On a cache miss the filter fell back to get_option(): with the values now written to the cache, the option is absent, so WordPress added its name to `notoptions` for good (dev36: +1,000 entries for 1,000 posts, one array loaded on every miss); a hit kept the old row in the options cache group with no expiry, which slowed the selective Redis flush (8.9 s, BUSY). The cache is now the only store for reads and deletes; old rows wait for cleanup-hp-transients --options. Without an object cache nothing changes.
- Verify: HivepressTransientFilterTest (2 RED before); dev36 notoptions 210 → 210 over 1,000 posts (was 128 → 1,128)
- PR: PR-089c
This commit is contained in:
2026-09-27 10:32:12 +08:00
parent c6faaebbc1
commit 788ddccfb3
3 changed files with 21 additions and 11 deletions
@@ -213,16 +213,18 @@ class HivepressTransientFilterTest extends TestCase {
$this->assertSame( array( '99999999' ), WPDO_Hivepress_Transient_Filter::on_read( null, 100, '_transient_timeout_hp_models/cat/v1', true ) );
}
public function test_with_an_object_cache_a_value_left_in_wp_options_still_reads(): void {
public function test_with_an_object_cache_a_value_left_in_wp_options_is_not_read(): void {
// A miss must not fall back to get_option(): the option is absent after
// cleanup and WordPress would add its name to `notoptions` for good.
$key = '_transient_hp_models/cat/v1';
$translated = WPDO_Hivepress_Transient_Filter::translate_key( 100, $key );
update_option( '_transient_' . $translated, 'from-before' );
$GLOBALS['_wp_using_ext_object_cache'] = true;
$this->assertSame( array( 'from-before' ), WPDO_Hivepress_Transient_Filter::on_read( null, 100, $key, true ) );
$this->assertNull( WPDO_Hivepress_Transient_Filter::on_read( null, 100, $key, true ) );
}
public function test_with_an_object_cache_delete_clears_both_stores(): void {
public function test_with_an_object_cache_delete_leaves_wp_options_alone(): void {
$key = '_transient_hp_models/cat/v1';
$translated = WPDO_Hivepress_Transient_Filter::translate_key( 100, $key );
update_option( '_transient_' . $translated, 'from-before' );
@@ -232,7 +234,7 @@ class HivepressTransientFilterTest extends TestCase {
WPDO_Hivepress_Transient_Filter::on_delete( null, 100, $key, '', false );
$this->assertNull( WPDO_Hivepress_Transient_Filter::on_read( null, 100, $key, true ) );
$this->assertFalse( get_option( '_transient_' . $translated ) );
$this->assertSame( 'from-before', get_option( '_transient_' . $translated ), 'left for cleanup-hp-transients --options' );
}
// ── count/purge legacy ──────────────────────────────────────────────────