[wp-trac] [WordPress Trac] #36814: get_the_terms() caches term count property
WordPress Trac
noreply at wordpress.org
Sun May 22 02:16:05 UTC 2016
#36814: get_the_terms() caches term count property
-------------------------------------+---------------------------
Reporter: ocean90 | Owner: boonebgorges
Type: defect (bug) | Status: reviewing
Priority: normal | Milestone: 4.6
Component: Taxonomy | Version:
Severity: normal | Resolution:
Keywords: has-patch needs-testing | Focuses:
-------------------------------------+---------------------------
Changes (by boonebgorges):
* keywords: needs-patch needs-unit-tests => has-patch needs-testing
Comment:
> Invalidate term cache when a post is updated that has a
term_relationship with that term.
On further review, more invalidation does *not* appear to be the right
answer. Here's the problem. Term data (classes with properties `term_id`,
`taxonomy`, `count`, etc) are currently cached in *two* places:
1. `wp_cache_set( $term_id, 'terms' )` (the single-term cache)
2. `wp_cache_set( $object_id, $terms, "{$taxonomy}_relationships" )` (the
object-term-relationships cache - `$terms` is an array of term objects)
When a term's `count` changes, cache 1 is invalidated correctly. Cache 2
is not, which is what causes the current bug. But to invalidate it
properly would mean busting the object relationship cache for *every
single object* associated with the term. In other words: A category `foo`
is associated with 100 posts (`count=100`). It's added to a new post.
Fixing the current bug by invalidating cache 2 means that *all 100 posts*
must have their relationship caches dumped. This is a lousy system.
There is a better way! The `{$taxonomy}_relationships` cache should be an
array of term IDs, rather than an array of term objects. Term objects can
then be pulled from the single-term cache. See [attachment:36814.diff].
A couple back compat concerns. First, to maintain the same return value
for `get_object_term_cache()` - an array of term objects - I had to move a
bunch of logic into there. In some rare cases, this may mean that calling
`get_object_term_cache()` results in a database query, in order to prime
the cache for the individual terms. It's very rare, because the query only
takes places when the `{$taxonomy}_relationships` cache is primed, but one
or more of the matching single-term caches is not. But this hardly ever
happens, because `get_object_term_cache()` is usually called in
conjunction with `wp_get_object_terms()` or another function that sets all
of these caches. I don't think this is actually a concern, but it's worth
mentioning for the record.
Second, the change means that the value stored in
`{$taxonomy}_relationships` is of a different format. Anyone directly
reading that value and expecting it to be term objects will have their
stuff break. I've done a search of the plugin repo and have found a very,
very small number of cases that would ever be affected by this. To be
extra safe, I've maintained support for plugins that *update* the
`{$taxonomy}_relationships` cache with term objects - this happens a bit
more frequently in the wild.
Anyone see problems with the approach I'm suggesting? I think it's far
more elegant than what we've currently got. (And it will make the cache
schema more compatible with a split term query, if we ever get around to
that; see #35381.)
--
Ticket URL: <https://core.trac.wordpress.org/ticket/36814#comment:4>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list