[wp-trac] [WordPress Trac] #36487: Hierarchical comments do not display on second call of comments_template

WordPress Trac noreply at wordpress.org
Sat May 14 03:17:28 UTC 2016


#36487: Hierarchical comments do not display on second call of comments_template
--------------------------+--------------------
 Reporter:  cookiesowns   |       Owner:
     Type:  defect (bug)  |      Status:  new
 Priority:  normal        |   Milestone:  4.6
Component:  Comments      |     Version:  4.4.2
 Severity:  normal        |  Resolution:
 Keywords:  has-patch     |     Focuses:
--------------------------+--------------------
Changes (by boonebgorges):

 * keywords:   => has-patch
 * milestone:  Awaiting Review => 4.6


Comment:

 @cookiesowns Thanks very much for the report and the preliminary
 diagnosis. You are quite correct.

 To spell out the problem a bit more: The `fill_descendants()` method
 builds its SQL strings out of the SQL strings built in
 `get_comment_ids()`. But if the main comment query is cached, then
 `get_comment_ids()` is never called, and those strings are never built.
 Thus, when you run the exact same comment query twice, the first time
 primes the `get_comment_ids` cache, and the second one hits that cache,
 resulting in a broken `fill_descendants()` query.

 Coming up with a "correct" fix for this is pretty difficult. In theory, I
 suppose it would be cleanest if the `fill_descendants()` queries were
 built totally independently of the `get_comment_ids()` queries. But this
 would require a fairly extensive rewrite of `WP_Comment_Query`, which is
 more than I can stomach at the moment.

 I propose [attachment:36487.diff] as an alternative solution. It's a bit
 tricky, but it is also much more localized - and it has the potential for
 auxiliary benefit. Here's the breakdown:

 - `fill_descendants()` crawls down each step of the hierarchy and runs a
 single SQL query to grab the child comments of a given level.
 - I've added a parent-child relationship cache. So, the first time
 `fill_descendants()` is run for a given set of query_vars, each located
 comment gets an array of its child-comment IDs stored in the cache.
 - Then, on subsequent calls to `fill_descendants()`, the query at each
 level of the hierarchy only queries for parents whose children are not
 found in the cache. For queries that are exact duplicates, *all* parents
 in the hierarchy should already be cached. So no additional SQL queries
 are run.
 - Note that the cache key has to be built out of the `query_vars`, since
 the hierarchy being cached depends on the params passed to
 `WP_Comment_Query`. (For example, running a query that includes
 `comment__not_in` might result in a cached hierarchy that is incomplete
 for subsequent queries that don't contain `comment__not_in`.) In order to
 make this reliable, I had to make a change to the logic of
 `get_comment_ids()` so that that method never changes the `query_vars`
 array (see the bit about `'parent'`).

 Strictly speaking, this doesn't directly address the technique used for
 building the SQL strings in `fill_descendants()`. The fix is indirect: the
 `fill_descendants()` queries should only be run when the
 `get_comment_child_ids` caches are empty, but anytime these caches are
 empty, it should be the case that `get_comment_ids()` has also been run,
 and thus the SQL strings available. As an added benefit, if the day ever
 comes when the 'comment' cache becomes persistent, [attachment:36487.diff]
 will result in meaningful performance enhancements across the board.

 Phew - it's a bit complicated. @cookiesowns, could you think about this
 logic, and test the patch to ensure it's behaving as you'd expect? (I
 could also use a review from someone else familiar with this rat's nest -
 maybe @rachelbaker?)

--
Ticket URL: <https://core.trac.wordpress.org/ticket/36487#comment:1>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list