[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