Skip to content

Commit ae6bbcf

Browse files
committed
Always clear the object cache after each chunk of comments and users
wp-cli/wp-cli#6426 makes the formatter read the requested fields of each item while it is current, also when it can't stream them. User meta and the post fields of comments are therefore read before the cache of their chunk is cleared, so the cache no longer needs to be kept for them. The posts of each chunk of comments are now loaded in one query, so that fields like post_title don't load each post again in every chunk. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D26yjkN2BiqCXT6p6o1WqS
1 parent e40ba44 commit ae6bbcf

2 files changed

Lines changed: 18 additions & 42 deletions

File tree

‎src/Comment_Command.php‎

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -524,8 +524,7 @@ public function list_( $args, $assoc_args ) {
524524

525525
// Threaded results are nested, so they can't be loaded in chunks.
526526
if ( ! in_array( $formatter->format, [ 'count', 'ids' ], true ) && empty( $assoc_args['hierarchical'] ) ) {
527-
$fields = $formatter->field ? [ $formatter->field ] : (array) $formatter->fields;
528-
$formatter->display_items( $this->query_comments_in_chunks( $assoc_args, $fields ) );
527+
$formatter->display_items( $this->query_comments_in_chunks( $assoc_args, $need_url ) );
529528
return;
530529
}
531530

@@ -574,23 +573,15 @@ function ( $comment ) {
574573
* a chunk at a time, and the object cache is cleared after each chunk. Formats that
575574
* can be written item by item are then streamed by the formatter.
576575
*
577-
* Fields that WP_Comment reads from the comment's post are read from the object
578-
* cache. If any of them are displayed, the cache is kept, because the formatter may
579-
* only read them once all comments have been loaded.
576+
* Fields that WP_Comment reads from the comment's post are read from the object cache.
577+
* The formatter reads the requested fields of each comment while it is the current
578+
* item, before the cache of its chunk is cleared, even when it can't stream them.
580579
*
581580
* @param array<string, mixed> $query_args WP_Comment_Query arguments.
582-
* @param string[] $fields Fields that will be displayed.
581+
* @param bool $need_url Whether to add the `url` property to each comment.
583582
* @return \Generator<int, \WP_Comment>
584583
*/
585-
private function query_comments_in_chunks( $query_args, $fields ) {
586-
$need_url = in_array( 'url', $fields, true );
587-
$clear_cache = true;
588-
foreach ( $fields as $field ) {
589-
if ( 'url' !== $field && ! property_exists( 'WP_Comment', $field ) && ! property_exists( 'WP_Comment', 'comment_' . $field ) ) {
590-
$clear_cache = false;
591-
}
592-
}
593-
584+
private function query_comments_in_chunks( $query_args, $need_url ) {
594585
$result = ( new WP_Comment_Query() )->query(
595586
array_merge(
596587
$query_args,
@@ -616,6 +607,8 @@ private function query_comments_in_chunks( $query_args, $fields ) {
616607
$chunk_args['fields'] = '';
617608
$chunk_args['count'] = false;
618609
$chunk_args['no_found_rows'] = true;
610+
// Load the posts of each chunk in one query, as fields like `post_title` read them.
611+
$chunk_args['update_comment_post_cache'] = true;
619612

620613
foreach ( array_chunk( $ids, self::LIST_CHUNK_SIZE ) as $chunk ) {
621614
$chunk_args['comment__in'] = $chunk;
@@ -641,9 +634,7 @@ private function query_comments_in_chunks( $query_args, $fields ) {
641634
}
642635

643636
unset( $comments );
644-
if ( $clear_cache ) {
645-
self::clear_runtime_object_cache();
646-
}
637+
self::clear_runtime_object_cache();
647638
}
648639
}
649640

‎src/User_Command.php‎

Lines changed: 9 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,8 @@ public function list_( $args, $assoc_args ) {
177177
} elseif ( 'count' === $formatter->format ) {
178178
$formatter->display_items( get_users( $assoc_args ) );
179179
} else {
180-
$fields = $formatter->field ? [ $formatter->field ] : (array) $formatter->fields;
181-
$formatter->display_items( $this->query_users_in_chunks( $assoc_args, $fields ) );
180+
$need_url = 'url' === $formatter->field || in_array( 'url', (array) $formatter->fields, true );
181+
$formatter->display_items( $this->query_users_in_chunks( $assoc_args, $need_url ) );
182182
}
183183
}
184184

@@ -189,28 +189,15 @@ public function list_( $args, $assoc_args ) {
189189
* loaded a chunk at a time, and the object cache is cleared after each chunk. Formats
190190
* that can be written item by item are then streamed by the formatter.
191191
*
192-
* User meta is read from the object cache. If any meta is displayed, the cache is
193-
* kept, because the formatter may only read it once all users have been loaded.
192+
* User meta is read from the object cache. The formatter reads the requested fields of
193+
* each user while it is the current item, before the cache of its chunk is cleared,
194+
* even when it can't stream them.
194195
*
195-
* @param array $query_args WP_User_Query arguments.
196-
* @param string[] $fields Fields that will be displayed.
196+
* @param array $query_args WP_User_Query arguments.
197+
* @param bool $need_url Whether to add the `url` property to each user.
197198
* @return \Generator<int, \WP_User>
198199
*/
199-
private function query_users_in_chunks( $query_args, $fields ) {
200-
$columns = [ 'ID', 'user_login', 'user_pass', 'user_nicename', 'user_email', 'user_url', 'user_registered', 'user_activation_key', 'user_status', 'display_name' ];
201-
$need_url = in_array( 'url', $fields, true );
202-
$clear_cache = true;
203-
foreach ( $fields as $field ) {
204-
if (
205-
! in_array( $field, [ 'url', 'roles' ], true )
206-
&& ! in_array( $field, $columns, true )
207-
&& ! in_array( 'user_' . $field, $columns, true )
208-
&& ! property_exists( 'WP_User', $field )
209-
) {
210-
$clear_cache = false;
211-
}
212-
}
213-
200+
private function query_users_in_chunks( $query_args, $need_url ) {
214201
$ids = array_map( 'intval', (array) get_users( array_merge( $query_args, [ 'fields' => 'ids' ] ) ) );
215202

216203
$chunk_args = $query_args;
@@ -244,9 +231,7 @@ private function query_users_in_chunks( $query_args, $fields ) {
244231
}
245232

246233
unset( $users );
247-
if ( $clear_cache ) {
248-
self::clear_runtime_object_cache();
249-
}
234+
self::clear_runtime_object_cache();
250235
}
251236
}
252237

0 commit comments

Comments
 (0)