Advertisement

WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Multisite

Aug. 13, 2011
Advertisement

More Related Content

Advertisement

WordCamp San Francisco 2011: Transients, Caching, and the Complexities of Multisite

  1. The Otto & Nacin Show WordCamp San Francisco 2011 August 12, 2011
  2. Nacin Otto Contributing Developers to WordPress Tech Ninjas at Audrey Capital nacin@wordpress.org otto@wordpress.org @nacin @otto42
  3. Transients, Caching, and the Complexities of Multisite (A brief overview.)
  4. Basic Caching with Transients
  5. Transients are ideal for: Temporary data that can expire at will.
  6. $value = get_transient( 'big_data' ); if ( false === $value ) { // do something that takes a fair amount of time $response = wp_remote_get( $url ); $value = wp_remote_retrieve_body( $response ); set_transient( 'big_data', $value, 60 * 60 * 24 ); } echo $value;
  7. $value = get_transient( 'big_data' ); if ( false === $value ) { // do something that takes a fair amount of time $response = wp_remote_get( $url ); $value = wp_remote_retrieve_body( $response ); set_transient( 'big_data', $value ); // this one doesn't expire, but it might anyway } echo $value;
  8. Always persistent: When there's no external object cache, WordPress uses the options table.
  9. Object Caching
  10. Object caching is ideal for: Caching an object (often a query result) to reduce overhead.
  11. $activity_object = wp_cache_get( $id, 'activity' ); if ( false === $activity_object ) { // begrudgingly fetch our object $activity_object = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $wpdb->activity WHERE ID = %d", $id ) ); wp_cache_set( $id, $activity_object , 'activity' ); } // do something with $activity_object
  12. Ideally persistent: Use an object caching backend like APC, Memcached, or WinCache.
  13. Object caching is not ideal if you need both data persistence and code portability. No knowledge of the server setup? Use transients.
  14. // Cache functions can take an expiration too wp_cache_set( $id, $activity_object , 'activity', $expires = 0 );
  15. Enter Multisite (Run.)
  16. Site Transients! Well, network-wide transients. Pardon the terminology.
  17. $value = get_site_transient( 'big_data' ); if ( false === $value ) { // do something that takes a fair amount of time $response = wp_remote_get( $url ); $value = wp_remote_retrieve_body( $response ); set_site_transient( 'big_data', $value, 86400 ); } echo $value;
  18. Always persistent: When there's no external object cache, WordPress uses the sitemeta table.
  19. It works in single-site! When not running multisite, it wraps *_transient().
  20. Global Cache Groups Cache groups ('activity') are site- specific. Tell WordPress what isn't.
  21. // WordPress core (simplified) wp_cache_add_global_groups( array( 'users', 'user_meta', 'site-transient', 'site-options', 'site-lookup', 'blog-lookup', 'blog-details', ) ); // You (not simplified) wp_cache_add_global_groups( 'activity' );
  22. As you might expect, it works just fine in single-site.
  23. And then there's switch_to_blog() With great power comes great responsibility.
  24. Rule 1 Don't use it. If you do, cache around it.
  25. // Example is a widget with posts from another site: $posts = wp_cache_get( 'recent_posts', $blog_id ); if ( false === $posts ) { switch_to_blog( $blog_id ); $posts = new WP_Query( . . . )->posts; wp_cache_set( $blog_id, $posts, 'recent_posts' ); restore_current_blog(); // OMG BBQ } // do something with $posts
  26. // And for some extra credit: add_action( 'init', function() { wp_cache_add_global_groups( 'recent_posts' ); } ); add_action( 'save_post', function() { global $blog_id; if ( ! in_array( $blog_id, array( 1, 2 3, 4 ) ) return; wp_cache_delete( $blog_id, 'recent_posts' ); // And for even more extra credit: $posts = new WP_Query( . . . )->posts; wp_cache_add( $blog_id, $posts, 'recent_posts' ); } );
  27. Thanks! Questions? @otto42 @nacin
Advertisement