Networks and Sites: Lazy load site meta.

In [36566] a framework to lazily load metadata was introduced. This supported term and comment meta by default. In this commit, extends support for site ( blog ) meta. Site meta is not heavily used by core and is used by developers to extend multisite. In this change, `_prime_site_caches` and `WP_Site_Query` now call the new function `wp_lazyload_site_meta`. The function `wp_lazyload_site_meta` accepts an array of ids and adds them to the queue of metadata to be lazily loaded. The function `get_blogs_of_user` was updated to now lazily load site meta. 

Follow on from [55671].

Props spacedmonkey, johnjamesjacoby, peterwilsoncc, mukesh27.
Fixes #58185.

git-svn-id: https://develop.svn.wordpress.org/trunk@55747 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Jonny Harris
2023-05-11 11:13:10 +00:00
parent bd92ca233d
commit 1a5b52a17e
6 changed files with 107 additions and 7 deletions

View File

@@ -61,6 +61,10 @@ class WP_Metadata_Lazyloader {
'filter' => 'get_comment_metadata',
'callback' => array( $this, 'lazyload_meta_callback' ),
),
'blog' => array(
'filter' => 'get_blog_metadata',
'callback' => array( $this, 'lazyload_meta_callback' ),
),
);
}

View File

@@ -388,6 +388,10 @@ class WP_Site_Query {
$site_ids = array_map( 'intval', $site_ids );
if ( $this->query_vars['update_site_meta_cache'] ) {
wp_lazyload_site_meta( $site_ids );
}
if ( 'ids' === $this->query_vars['fields'] ) {
$this->sites = $site_ids;
@@ -396,7 +400,7 @@ class WP_Site_Query {
// Prime site network caches.
if ( $this->query_vars['update_site_cache'] ) {
_prime_site_caches( $site_ids, $this->query_vars['update_site_meta_cache'] );
_prime_site_caches( $site_ids, false );
}
// Fetch full site objects from the primed cache.

View File

@@ -340,6 +340,7 @@ function get_site( $site = null ) {
* @since 4.6.0
* @since 5.1.0 Introduced the `$update_meta_cache` parameter.
* @since 6.1.0 This function is no longer marked as "private".
* @since 6.3.0 Use wp_lazyload_site_meta() for lazy-loading of site meta.
*
* @see update_site_cache()
* @global wpdb $wpdb WordPress database abstraction object.
@@ -354,8 +355,27 @@ function _prime_site_caches( $ids, $update_meta_cache = true ) {
if ( ! empty( $non_cached_ids ) ) {
$fresh_sites = $wpdb->get_results( sprintf( "SELECT * FROM $wpdb->blogs WHERE blog_id IN (%s)", implode( ',', array_map( 'intval', $non_cached_ids ) ) ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
update_site_cache( $fresh_sites, $update_meta_cache );
update_site_cache( $fresh_sites, false );
}
if ( $update_meta_cache ) {
wp_lazyload_site_meta( $ids );
}
}
/**
* Queue site meta for lazy-loading.
*
* @since 6.3.0
*
* @param array $site_ids List of site IDs.
*/
function wp_lazyload_site_meta( array $site_ids ) {
if ( empty( $site_ids ) ) {
return;
}
$lazyloader = wp_metadata_lazyloader();
$lazyloader->queue_objects( 'blog', $site_ids );
}
/**

View File

@@ -1004,9 +1004,8 @@ function get_blogs_of_user( $user_id, $all = false ) {
if ( ! empty( $site_ids ) ) {
$args = array(
'number' => '',
'site__in' => $site_ids,
'update_site_meta_cache' => false,
'number' => '',
'site__in' => $site_ids,
);
if ( ! $all ) {
$args['archived'] = 0;

View File

@@ -281,6 +281,7 @@ abstract class WP_UnitTestCase_Base extends PHPUnit_Adapter_TestCase {
$lazyloader = wp_metadata_lazyloader();
$lazyloader->reset_queue( 'term' );
$lazyloader->reset_queue( 'comment' );
$lazyloader->reset_queue( 'blog' );
}
/**

View File

@@ -248,7 +248,79 @@ if ( is_multisite() ) :
$num_queries = get_num_queries();
get_site_meta( self::$site_id, 'foo', true );
$this->assertSame( $num_queries, get_num_queries() );
$this->assertSame( 1, get_num_queries() - $num_queries );
}
/**
* @ticket 58185
*/
public function test_lazy_load_site_meta() {
if ( ! is_site_meta_supported() ) {
$this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' );
}
$filter = new MockAction();
add_filter( 'update_blog_metadata_cache', array( $filter, 'filter' ), 10, 2 );
$q = new WP_Site_Query(
array(
'ID' => self::$site_id,
)
);
$this->assertSameSets( array( (string) self::$site_id ), wp_list_pluck( $q->sites, 'blog_id' ), 'Site query should return the first test site' );
$q = new WP_Site_Query(
array(
'ID' => self::$site_id2,
)
);
$this->assertSameSets( array( (string) self::$site_id2 ), wp_list_pluck( $q->sites, 'blog_id' ), 'Site query should return the second test site' );
get_site_meta( self::$site_id2 );
$args = $filter->get_args();
$first = reset( $args );
$site_ids = end( $first );
$this->assertSameSets( $site_ids, array( self::$site_id, self::$site_id2 ), 'This should have two site\'s meta' );
}
/**
* @ticket 58185
*/
public function test_lazy_load_site_meta_fields_id() {
if ( ! is_site_meta_supported() ) {
$this->markTestSkipped( 'Test only runs with the blogmeta database table installed.' );
}
$filter = new MockAction();
add_filter( 'update_blog_metadata_cache', array( $filter, 'filter' ), 10, 2 );
$q = new WP_Site_Query(
array(
'ID' => self::$site_id,
'fields' => 'ids',
)
);
$this->assertSameSets( array( self::$site_id ), $q->sites, 'Site query should return the first test site' );
$q = new WP_Site_Query(
array(
'ID' => self::$site_id2,
'fields' => 'ids',
)
);
$this->assertSameSets( array( self::$site_id2 ), $q->sites, 'Site query should return the second test site' );
get_site_meta( self::$site_id2 );
$args = $filter->get_args();
$first = reset( $args );
$site_ids = end( $first );
$this->assertSameSets( $site_ids, array( self::$site_id, self::$site_id2 ), 'This should have two sites meta' );
}
public function test_query_update_site_meta_cache_false() {
@@ -267,7 +339,7 @@ if ( is_multisite() ) :
$num_queries = get_num_queries();
get_site_meta( self::$site_id, 'foo', true );
$this->assertSame( $num_queries + 1, get_num_queries() );
$this->assertSame( 1, get_num_queries() - $num_queries );
}
/**