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

27
The Otto & Nacin Show WordCamp San Francisco 2011 August 12, 2011

description

"The Otto & Nacin Show" at WordCamp San Francisco, on August 12, 2011, covered transients, caching, and how multisite complicates these.

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

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

The Otto & Nacin Show

WordCamp San Francisco 2011 August 12, 2011

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

Nacin

[email protected] @nacin

[email protected] @otto42

Contributing Developers to WordPress Tech Ninjas at Audrey Capital

Otto

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

Transients, Caching, and the Complexities of Multisite (A brief overview.)

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

Basic Caching with Transients

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

Transients are ideal for: Temporary data that can expire at will.

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

$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;

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

$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;

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

Always persistent: When there's no external object cache, WordPress uses the options table.

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

Object Caching

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

Object caching is ideal for: Caching an object (often a query result) to reduce overhead.

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

$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

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

Ideally persistent: Use an object caching backend like APC, Memcached, or WinCache.

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

Object caching is not ideal if you need both data persistence and code portability. No knowledge of the server setup? Use transients.

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

// Cache functions can take an expiration too wp_cache_set( $id, $activity_object ,

'activity', $expires = 0 );

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

Enter Multisite

(Run.)

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

Site Transients!

Well, network-wide transients. Pardon the terminology.

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

$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;

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

Always persistent: When there's no external object cache, WordPress uses the sitemeta table.

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

It works in single-site! When not running multisite, it wraps *_transient().

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

Global Cache Groups

Cache groups ('activity') are site-specific. Tell WordPress what isn't.

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

// 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' );

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

As you might expect, it works just fine in single-site.

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

And then there's switch_to_blog()

With great power comes great responsibility.

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

Rule 1 Don't use it.

If you do, cache around it.

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

// 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

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

// 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' ); } );

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

Thanks! Questions?

@otto42 @nacin