hardening 2.2: 2meet-data-optimizer-hivepress-addon 0.3.0 (transients in the object cache) #3
+6
-4
@@ -20,10 +20,12 @@ Released with 2meet-data-optimizer 1.2.0 (hardening 2.2).
|
|||||||
- With a persistent object cache (`wp_using_ext_object_cache()`), the
|
- With a persistent object cache (`wp_using_ext_object_cache()`), the
|
||||||
transient filter keeps HivePress's per-post transient pairs in the
|
transient filter keeps HivePress's per-post transient pairs in the
|
||||||
`tmdo_hp_transient` cache group instead of `wp_options`, where they piled
|
`tmdo_hp_transient` cache group instead of `wp_options`, where they piled
|
||||||
up (1.15 M pairs on dev36). Reads fall back to `wp_options` for values
|
up (1.15 M pairs on dev36). The cache is then the only store: rows written
|
||||||
written before; deletes clear both. Without an object cache nothing changes.
|
before are neither read nor deleted (HivePress rebuilds those caches once),
|
||||||
After upgrading, remove the rows left behind with core's
|
because a `get_option()` miss adds the name to WordPress's `notoptions` for
|
||||||
`wp tmdo cleanup-hp-transients --options --confirm`.
|
good and a hit keeps the old row in the `options` cache group with no expiry.
|
||||||
|
Without an object cache nothing changes. After upgrading, remove the rows
|
||||||
|
left behind with core's `wp tmdo cleanup-hp-transients --options --confirm`.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
|||||||
@@ -167,9 +167,14 @@ final class TMDO_Hivepress_Transient_Filter {
|
|||||||
// HivePress cache layer reads the timeout *first*, then decides whether
|
// HivePress cache layer reads the timeout *first*, then decides whether
|
||||||
// to read the value. We must preserve raw stored values until HivePress
|
// to read the value. We must preserve raw stored values until HivePress
|
||||||
// itself orders deletion.
|
// itself orders deletion.
|
||||||
$value = wp_using_ext_object_cache() ? wp_cache_get( $option_name, self::CACHE_GROUP ) : false;
|
if ( wp_using_ext_object_cache() ) {
|
||||||
if ( false === $value ) {
|
// The object cache is the only store. Rows left in wp_options from
|
||||||
// wp_options: where values went before an object cache was used.
|
// before are not read (`wp tmdo cleanup-hp-transients --options`
|
||||||
|
// removes them): a get_option() miss would add the name to
|
||||||
|
// `notoptions` for good, as later writes never reach wp_options.
|
||||||
|
$value = wp_cache_get( $option_name, self::CACHE_GROUP );
|
||||||
|
$value = false === $value ? null : $value;
|
||||||
|
} else {
|
||||||
$value = get_option( $option_name, null );
|
$value = get_option( $option_name, null );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,6 +253,7 @@ final class TMDO_Hivepress_Transient_Filter {
|
|||||||
|
|
||||||
if ( wp_using_ext_object_cache() ) {
|
if ( wp_using_ext_object_cache() ) {
|
||||||
wp_cache_delete( $option_name, self::CACHE_GROUP );
|
wp_cache_delete( $option_name, self::CACHE_GROUP );
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
delete_option( $option_name );
|
delete_option( $option_name );
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -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 ) );
|
$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';
|
$key = '_transient_hp_models/cat/v1';
|
||||||
$translated = WPDO_Hivepress_Transient_Filter::translate_key( 100, $key );
|
$translated = WPDO_Hivepress_Transient_Filter::translate_key( 100, $key );
|
||||||
update_option( '_transient_' . $translated, 'from-before' );
|
update_option( '_transient_' . $translated, 'from-before' );
|
||||||
$GLOBALS['_wp_using_ext_object_cache'] = true;
|
$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';
|
$key = '_transient_hp_models/cat/v1';
|
||||||
$translated = WPDO_Hivepress_Transient_Filter::translate_key( 100, $key );
|
$translated = WPDO_Hivepress_Transient_Filter::translate_key( 100, $key );
|
||||||
update_option( '_transient_' . $translated, 'from-before' );
|
update_option( '_transient_' . $translated, 'from-before' );
|
||||||
@@ -232,7 +234,7 @@ class HivepressTransientFilterTest extends TestCase {
|
|||||||
WPDO_Hivepress_Transient_Filter::on_delete( null, 100, $key, '', false );
|
WPDO_Hivepress_Transient_Filter::on_delete( null, 100, $key, '', false );
|
||||||
|
|
||||||
$this->assertNull( WPDO_Hivepress_Transient_Filter::on_read( null, 100, $key, true ) );
|
$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 ──────────────────────────────────────────────────
|
// ── count/purge legacy ──────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user