fix(2meet-data-optimizer): skip cold-zone cache warming unless the cold module is active
- TMDO_Cache_Layer::prefetch() / warm_post() (and so on_save_post /
on_loop_start) queried wp_wpdo_cold_{post_type} whenever cold fields
were registered, even with the cold module idle and the table never
created: every HivePress / WC save logged "table doesn't exist" errors.
They now return unless the module is write-active and the table exists.
- CacheLayerTest activates the module in setUp; new cases assert zero cold
queries while idle or when the table is missing.
- Verify: CacheLayerTest 12 OK; unit 671 OK, integration 480 OK,
phpcs (phpcs.xml) 0, stan OK; dev36 live: seeding listings/products/
vendors with cold_hp_listing idle → 0 wpdo_cold errors (was hundreds)
- PR: PR-054
This commit is contained in:
@@ -40,7 +40,7 @@ class TMDO_Cache_Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$cold_keys = TMDO_Schema_Registry::instance()->get_cold_meta_keys( $post_type );
|
$cold_keys = TMDO_Schema_Registry::instance()->get_cold_meta_keys( $post_type );
|
||||||
if ( empty( $cold_keys ) ) {
|
if ( empty( $cold_keys ) || ! self::cold_active( $post_type ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ class TMDO_Cache_Layer {
|
|||||||
*/
|
*/
|
||||||
public static function warm_post( int $post_id, string $post_type ): void {
|
public static function warm_post( int $post_id, string $post_type ): void {
|
||||||
$cold_keys = TMDO_Schema_Registry::instance()->get_cold_meta_keys( $post_type );
|
$cold_keys = TMDO_Schema_Registry::instance()->get_cold_meta_keys( $post_type );
|
||||||
if ( empty( $cold_keys ) ) {
|
if ( empty( $cold_keys ) || ! self::cold_active( $post_type ) ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +120,19 @@ class TMDO_Cache_Layer {
|
|||||||
TMDO_Zone_Cold::get_blob( $post_id, $post_type );
|
TMDO_Zone_Cold::get_blob( $post_id, $post_type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the cold zone holds data for this post type: its module writes
|
||||||
|
* to the cold table and the table exists. Registered cold fields alone do
|
||||||
|
* not mean either (zero side effect while the module is idle).
|
||||||
|
*
|
||||||
|
* @param string $post_type Post type.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function cold_active( string $post_type ): bool {
|
||||||
|
return TMDO_Feature_Flags::is_write_active( TMDO_Zone_Router::module_name( 'cold', $post_type ) )
|
||||||
|
&& TMDO_Schema_Manager::table_exists( TMDO_Zone_Cold::table( $post_type ) );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush all cold cache for a post type.
|
* Flush all cold cache for a post type.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -11,17 +11,35 @@ class CacheLayerTest extends TestCase {
|
|||||||
/** Rows returned by get_results() for the bulk-fetch query. */
|
/** Rows returned by get_results() for the bulk-fetch query. */
|
||||||
public static array $db_rows = [];
|
public static array $db_rows = [];
|
||||||
|
|
||||||
|
/** Whether SHOW TABLES reports the cold table. */
|
||||||
|
public static bool $table_exists = true;
|
||||||
|
|
||||||
|
/** Queries that read the cold table (get_var / get_results on it). */
|
||||||
|
public static int $cold_queries = 0;
|
||||||
|
|
||||||
protected function setUp(): void {
|
protected function setUp(): void {
|
||||||
self::$db_rows = [];
|
self::$db_rows = [];
|
||||||
|
self::$table_exists = true;
|
||||||
|
self::$cold_queries = 0;
|
||||||
$GLOBALS['_wp_cache'] = [];
|
$GLOBALS['_wp_cache'] = [];
|
||||||
|
|
||||||
// Reset Schema Registry singleton.
|
// Reset Schema Registry singleton.
|
||||||
$ref = new ReflectionClass( WPDO_Schema_Registry::class );
|
$ref = new ReflectionClass( WPDO_Schema_Registry::class );
|
||||||
$ref->getProperty( 'instance' )->setValue( null, null );
|
$ref->getProperty( 'instance' )->setValue( null, null );
|
||||||
|
|
||||||
|
// The cold module is write-active unless a test says otherwise.
|
||||||
|
$this->set_cold_module( 'dual_write' );
|
||||||
|
WPDO_Schema_Manager::flush_table_exists_cache();
|
||||||
|
|
||||||
$this->setup_wpdb_mock();
|
$this->setup_wpdb_mock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function set_cold_module( string $state ): void {
|
||||||
|
$GLOBALS['_wp_options']['wpdo_features'] = array( 'cold_hp_listing' => $state );
|
||||||
|
$prop = new ReflectionProperty( WPDO_Feature_Flags::class, 'cache' );
|
||||||
|
$prop->setValue( null, null );
|
||||||
|
}
|
||||||
|
|
||||||
private function setup_wpdb_mock(): void {
|
private function setup_wpdb_mock(): void {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
|
|
||||||
@@ -36,7 +54,15 @@ class CacheLayerTest extends TestCase {
|
|||||||
}, $sql );
|
}, $sql );
|
||||||
}
|
}
|
||||||
|
|
||||||
public function get_var( string $sql ): ?string { return null; }
|
public function get_var( string $sql ): ?string {
|
||||||
|
if ( preg_match( "/^SHOW TABLES LIKE '(.+)'$/", $sql, $m ) ) {
|
||||||
|
return CacheLayerTest::$table_exists ? stripslashes( $m[1] ) : null;
|
||||||
|
}
|
||||||
|
if ( str_contains( $sql, 'wpdo_cold_' ) ) {
|
||||||
|
++CacheLayerTest::$cold_queries;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
public function get_row( string $sql, $output = OBJECT ) { return null; }
|
public function get_row( string $sql, $output = OBJECT ) { return null; }
|
||||||
public function insert( string $table, array $data, $format = null ): int|false { return 1; }
|
public function insert( string $table, array $data, $format = null ): int|false { return 1; }
|
||||||
public function update( string $table, array $data, array $where, $f = null, $wf = null ): int|false { return 1; }
|
public function update( string $table, array $data, array $where, $f = null, $wf = null ): int|false { return 1; }
|
||||||
@@ -44,11 +70,45 @@ class CacheLayerTest extends TestCase {
|
|||||||
public function query( string $sql ): int|bool { return 1; }
|
public function query( string $sql ): int|bool { return 1; }
|
||||||
|
|
||||||
public function get_results( string $sql, $output = OBJECT ): array {
|
public function get_results( string $sql, $output = OBJECT ): array {
|
||||||
|
if ( str_contains( $sql, 'wpdo_cold_' ) ) {
|
||||||
|
++CacheLayerTest::$cold_queries;
|
||||||
|
}
|
||||||
return CacheLayerTest::$db_rows;
|
return CacheLayerTest::$db_rows;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── Zero side effect while the cold module is not active ─────────────────
|
||||||
|
|
||||||
|
public function test_prefetch_does_not_query_while_module_idle(): void {
|
||||||
|
$this->register_cold_field();
|
||||||
|
$this->set_cold_module( 'idle' );
|
||||||
|
|
||||||
|
WPDO_Cache_Layer::prefetch( [ 1, 2 ], 'hp_listing' );
|
||||||
|
|
||||||
|
$this->assertSame( 0, self::$cold_queries );
|
||||||
|
$this->assertEmpty( $GLOBALS['_wp_cache'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_warm_post_does_not_query_while_module_idle(): void {
|
||||||
|
$this->register_cold_field();
|
||||||
|
$this->set_cold_module( 'idle' );
|
||||||
|
|
||||||
|
WPDO_Cache_Layer::warm_post( 20, 'hp_listing' );
|
||||||
|
|
||||||
|
$this->assertSame( 0, self::$cold_queries );
|
||||||
|
}
|
||||||
|
|
||||||
|
public function test_no_query_when_cold_table_is_missing(): void {
|
||||||
|
$this->register_cold_field();
|
||||||
|
self::$table_exists = false;
|
||||||
|
|
||||||
|
WPDO_Cache_Layer::prefetch( [ 1 ], 'hp_listing' );
|
||||||
|
WPDO_Cache_Layer::warm_post( 1, 'hp_listing' );
|
||||||
|
|
||||||
|
$this->assertSame( 0, self::$cold_queries );
|
||||||
|
}
|
||||||
|
|
||||||
// ── Helper: register cold field ──────────────────────────────────────────
|
// ── Helper: register cold field ──────────────────────────────────────────
|
||||||
|
|
||||||
private function register_cold_field( string $post_type = 'hp_listing', string $meta_key = 'hp_description' ): void {
|
private function register_cold_field( string $post_type = 'hp_listing', string $meta_key = 'hp_description' ): void {
|
||||||
|
|||||||
Reference in New Issue
Block a user