Make WordPress Core


Ignore:
Timestamp:
07/03/2014 04:44:15 PM (12 years ago)
Author:
helen
Message:

Improve oEmbed caching. Introduces the concept of a TTL for oEmbed caches and a filter for oembed_ttl.

We will no longer replace previously valid oEmbed responses with an {{unknown}} cache value. When this happens due to reaching a rate limit or a service going down, it is data loss, and is not acceptable. This means that oEmbed caches for a post are no longer deleted indiscriminately every time that post is saved.

oEmbed continues to be cached in post meta, with the addition of a separate meta key containing the timestamp of the last retrieval, which is used to avoid re-requesting a recently cached oEmbed response. By default, we consider a valued cached in the past day to be fresh. This can greatly reduce the number of outbound requests, especially in cases where a post containing multiple embeds is saved frequently.

The TTL used to determine whether or not to request a response can be filtered using oembed_ttl, thus allowing for the possibility of respecting the optional oEmbed response parameter cache_age or altering the period of time a cached value is considered to be fresh.

Now that oEmbeds are previewed in the visual editor as well as the media modal, oEmbed caches are often populated before a post is saved or published. By pre-populating and avoiding having to re-request that response, we also greatly reduce the chances of a stampede happening when a published post is visible before oEmbed caching is complete.

As it previously stood, a stampede was extremely likely to happen, as the AJAX caching was only triggered when $_GET['message'] was 1. The published message is 6. We now trigger the caching every time $_GET['message'] is present on the edit screen, as we are able to avoid triggering so many HTTP requests overall.

props markjaquith. fixes #14759. see #17210.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-embed.php

    r28923 r28972  
    3232                add_filter( 'the_content', array( $this, 'autoembed' ), 8 );
    3333
    34                 // When a post is saved, invalidate the oEmbed cache
    35                 add_action( 'pre_post_update', array( $this, 'delete_oembed_caches' ) );
    36 
    3734                // After a post is saved, cache oEmbed items via AJAX
    3835                add_action( 'edit_form_advanced', array( $this, 'maybe_run_ajax_cache' ) );
    … …  
    7976                $post = get_post();
    8077
    81                 if ( ! $post || empty($_GET['message']) || 1 != $_GET['message'] )
     78                if ( ! $post || empty( $_GET['message'] ) )
    8279                        return;
    8380
    … …  
    193190
    194191                        // Check for a cached result (stored in the post meta)
    195                         $cachekey = '_oembed_' . md5( $url . serialize( $attr ) );
    196                         if ( $this->usecache ) {
    197                                 $cache = get_post_meta( $post_ID, $cachekey, true );
    198 
    199                                 // Failures are cached
     192                        $key_suffix = md5( $url . serialize( $attr ) );
     193                        $cachekey = '_oembed_' . $key_suffix;
     194                        $cachekey_time = '_oembed_time_' . $key_suffix;
     195
     196                        /**
     197                         * Filter the oEmbed TTL (time to live).
     198                         *
     199                         * @since 4.0.0
     200                         *
     201                         * @param string $url     The attempted embed URL.
     202                         * @param array  $attr    An array of shortcode attributes.
     203                         * @param int    $post_ID Post ID.
     204                         */
     205                        $ttl = apply_filters( 'oembed_ttl', DAY_IN_SECONDS, $url, $attr, $post_ID );
     206
     207                        $cache = get_post_meta( $post_ID, $cachekey, true );
     208                        $cache_time = get_post_meta( $post_ID, $cachekey_time, true );
     209
     210                        if ( ! $cache_time ) {
     211                                $cache_time = 0;
     212                        }
     213
     214                        $cached_recently = ( time() - $cache_time ) < $ttl;
     215
     216                        if ( $this->usecache || $cached_recently ) {
     217                                // Failures are cached. Serve one if we're using the cache.
    200218                                if ( '{{unknown}}' === $cache )
    201219                                        return $this->maybe_make_link( $url );
    202220
    203                                 if ( ! empty( $cache ) )
     221                                if ( ! empty( $cache ) ) {
    204222                                        /**
    205223                                         * Filter the cached oEmbed HTML.
    … …  
    215233                                         */
    216234                                        return apply_filters( 'embed_oembed_html', $cache, $url, $attr, $post_ID );
     235                                }
    217236                        }
    218237
    … …  
    231250                        $html = wp_oembed_get( $url, $attr );
    232251
    233                         // Cache the result
    234                         $cache = ( $html ) ? $html : '{{unknown}}';
    235                         update_post_meta( $post_ID, $cachekey, $cache );
     252                        // Maybe cache the result
     253                        if ( $html ) {
     254                                update_post_meta( $post_ID, $cachekey, $html );
     255                                update_post_meta( $post_ID, $cachekey_time, time() );
     256                        } elseif ( ! $cache ) {
     257                                update_post_meta( $post_ID, $cachekey, '{{unknown}}' );
     258                        }
    236259
    237260                        // If there was a result, return it
    … …  
    247270
    248271        /**
    249          * Delete all oEmbed caches.
     272         * Delete all oEmbed caches. Unused by core as of 4.0.0.
    250273         *
    251274         * @param int $post_ID Post ID to delete the caches for.
Note: See TracChangeset for help on using the changeset viewer.