wordcamp san francisco 2011: transients, caching, and the complexities of multisite

Post on 21-May-2015

5.945 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

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

TRANSCRIPT

The Otto & Nacin Show

WordCamp San Francisco 2011 August 12, 2011

Nacin

nacin@wordpress.org @nacin

otto@wordpress.org @otto42

Contributing Developers to WordPress Tech Ninjas at Audrey Capital

Otto

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

Basic Caching with Transients

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

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

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

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

Object Caching

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

$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

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

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

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

'activity', $expires = 0 );

Enter Multisite

(Run.)

Site Transients!

Well, network-wide transients. Pardon the terminology.

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

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

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

Global Cache Groups

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

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

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

And then there's switch_to_blog()

With great power comes great responsibility.

Rule 1 Don't use it.

If you do, cache around it.

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

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

Thanks! Questions?

@otto42 @nacin

top related