Skip to:
Content

Opened 2 years ago

Last modified 2 years ago

#3034 new defect

Every new topic/reply invalidates the get_sites() cache

Reported by: wpdennis Owned by: johnjamesjacoby
Milestone: 2.7 Priority: high
Severity: normal Version: 2.0
Component: API - Cache Keywords: dev-feedback needs-patch needs-testing
Cc: info@…

Description

It's not a bbPress bug, but the current WordPress behaviour creates an insane amount (as in millions) of cache entries just for the cache group "sites", if an active community is participating in a bbPress forum - or any plugin based on creating and editing posts for that matter.

With every wp_insert_post() a call to _update_blog_date_on_post_publish() is triggered and eventually runs

wp_cache_set( 'last_changed', microtime(), 'sites' );

in clean_blog_cache(). This forces WP_Site_Query->get_sites() to create new cache entries for each incoming request.

wp_insert_post() is called every time a new {post_type} (reply/topic/forum) is created or edited.

Is this necessary? What are your thoughts?

Change History (4)

#1 @johnjamesjacoby
2 years ago

This is not ideal, but currently "by design."

The cached data that needs updating is in wp_blogs::last_updated, which changes when public post-types are published. This is relevant for bbPress forums, topics, and replies, but can certainly cause exactly the problem you describe.

A few thoughts:

  • We could temporarily disable core caches, and handle it all within bbPress conditionally
  • We could spend a bit more time looking into the exact call-stack, and make sure WordPress has adequate actions & filters to allow for limiting some of this cache churn

#2 @wpdennis
2 years ago

Yes exactly. Changing "last_updated" is the reason for this. The call stack is:

wp_insert_post
wp_transition_post_status
_update_blog_date_on_post_publish
wpmu_update_blogs_date
update_blog_details
refresh_blog_details
clean_blog_cache

This is triggered by every wp_insert_post() and since wp_update_post() calls wp_insert_post() every edit runs clean_blog_cache(), too.

_update_blog_date_on_post_publish() is hooked into wp_transition_post_status but doesn't need a transition (by design), it just checks whether the post is or was published.

bbPress triggers this by his 3 bbp_new_{post_type}_handler and 3 bbp_edit_{post_type}_handler and bbp_spam_topic:

bbp_get_request
bbp_toggle_topic_handler
bbp_spam_topic

I was able to avoid this behaviour by removing hooks like this:

add_action( 'bbp_new_reply_pre_extras', function() {
    remove_action( 'transition_post_status', '_update_blog_date_on_post_publish', 10, 3 );
} );
add_action( 'bbp_edit_reply_pre_extras', function() {
    remove_action( 'transition_post_status', '_update_blog_date_on_post_publish', 10, 3 );
} );

But this way "last_updated" will not get changed anymore. I'm not sure what side effects this will cause.

This ticket was mentioned in Slack in #core-multisite by jjj. View the logs.


2 years ago

#4 @johnjamesjacoby
2 years ago

  • Component changed from General to API - Cache
  • Keywords needs-patch needs-testing added
  • Milestone changed from Awaiting Review to 2.7
  • Owner set to johnjamesjacoby
  • Priority changed from normal to high
  • Version set to 2.0

We had some really good discussion about this, here:

https://wordpress.slack.com/archives/core-multisite/p1488898458135726

I'd like to push this to 2.7, to help get 2.6 out eventually. It's a fun problem to solve, and we will solve it, but it may require some changes upstream to WordPress to do so.

Note: See TracTickets for help on using tickets.