[wp-trac] [WordPress Trac] #47884: Unable to remove "counts" from non persistent cache groups
WordPress Trac
noreply at wordpress.org
Thu Aug 25 22:21:57 UTC 2022
#47884: Unable to remove "counts" from non persistent cache groups
------------------------------+--------------------------
Reporter: Maciej Laskowski | Owner: (none)
Type: defect (bug) | Status: closed
Priority: normal | Milestone:
Component: Cache API | Version: 2.6
Severity: normal | Resolution: wontfix
Keywords: | Focuses: performance
------------------------------+--------------------------
Comment (by tha_sun):
The group `"counts"` is marked as non-persistent, because
`wp_count_posts()` is creating user-specific cache items, counting the
amount of private posts the user is able to access:
https://github.com/WordPress/WordPress/blob/668a2ec9ffbbdbda006c257b7a21ea12273b6082
/wp-includes/post.php#L3036-L3048
{{{#!php
<?php
$query = "SELECT post_status, COUNT( * ) AS num_posts FROM
{$wpdb->posts} WHERE post_type = %s";
if ( 'readable' === $perm && is_user_logged_in() ) {
$post_type_object = get_post_type_object( $type );
if ( ! current_user_can(
$post_type_object->cap->read_private_posts ) ) {
$query .= $wpdb->prepare(
" AND (post_status != 'private' OR (
post_author = %d AND post_status = 'private' ))",
get_current_user_id()
);
}
}
$query .= ' GROUP BY post_status';
}}}
As there are unlimited possible user IDs, it is impossible to invalidate
all cache items when posts are saved.
`_transition_post_status()` invalidates the non-user-specific cache item:
https://github.com/WordPress/WordPress/blob/668a2ec9ffbbdbda006c257b7a21ea12273b6082
/wp-includes/post.php#L7647-L7650
{{{#!php
<?php
if ( $new_status !== $old_status ) {
wp_cache_delete( _count_posts_cache_key( $post->post_type
), 'counts' );
wp_cache_delete( _count_posts_cache_key( $post->post_type,
'readable' ), 'counts' );
}
}}}
It also invalidates the cache item of the currently logged-in user. But
it does not invalidate the cache items for other users.
A solution to this would be to introduce a new Object Cache API method
`wp_cache_flush_group()` that allows to flush all items in the given
group. Some backends would support this natively, some others would need
to loop over (all) keys to find the ones to remove. `wp_count_posts()`
would then use a combined group name of `counts:{$post_type}`.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/47884#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list