WordPress.org

Make WordPress Core

Ticket #22301: 22301.2.diff

File 22301.2.diff, 3.0 KB (added by kovshenin, 7 years ago)
  • src/wp-includes/default-widgets.php

     
    811811        }
    812812
    813813        public function flush_widget_cache() {
    814                 wp_cache_delete('widget_recent_comments', 'widget');
     814                $cache = wp_cache_get( 'widget_recent_comments', 'widget' );
     815                if ( ! empty( $cache ) ) {
     816                        // If the cache is flushed multiple times, we don't want to save an empty copy.
     817                        wp_cache_delete( 'widget_recent_comments', 'widget' );
     818                        wp_cache_set( 'widget_recent_comments_stale', $cache, 'widget' );
     819                }
    815820        }
    816821
    817         public function widget( $args, $instance ) {
    818                 global $comments, $comment;
     822        /**
     823         * Get cached data for a Recent Comments widget.
     824         *
     825         * Comment queries can be expensive so when the recent comments
     826         * cache is flushed, we keep a stale copy and serve it until the
     827         * updated data is rebuilt and cached.
     828         */
     829        public function get_widget_cache( $widget_id ) {
     830                if ( $this->is_preview() )
     831                        return;
    819832
    820                 $cache = array();
    821                 if ( ! $this->is_preview() ) {
    822                         $cache = wp_cache_get('widget_recent_comments', 'widget');
     833                $cache = wp_cache_get( 'widget_recent_comments', 'widget' );
     834
     835                if ( ! empty( $cache[ $widget_id ] ) ) {
     836                        // Cache is up to date.
     837                        return $cache[ $widget_id ];
     838                } else {
     839                        // Cache is outdated.
     840                        $cache = wp_cache_get( 'widget_recent_comments_stale', 'widget' );
    823841                }
    824                 if ( ! is_array( $cache ) ) {
     842
     843                // No data even in the outdated cache.
     844                if ( empty( $cache[ $widget_id ] ) )
     845                        return;
     846
     847                // Attempt to acquire a lock or serve the data from stale cache.
     848                if ( false === wp_cache_add( 'widget_recent_comments_lock', true, 'widget' ) )
     849                        return $cache[ $widget_id ];
     850
     851                // Lock acquired, return "empty" cache.
     852                return;
     853        }
     854
     855        /**
     856         * Updated a Recent Comments widget cache.
     857         */
     858        public function update_widget_cache( $widget_id, $data ) {
     859                if ( $this->is_preview() )
     860                        return;
     861
     862                $cache = wp_cache_get( 'widget_recent_comments', 'widget' );
     863                if ( ! is_array( $cache ) )
    825864                        $cache = array();
    826                 }
    827865
     866                $cache[ $widget_id ] = $data;
     867                wp_cache_set( 'widget_recent_comments', $cache, 'widget' );
     868                wp_cache_delete( 'widget_recent_comments_lock', 'widget' );
     869        }
     870
     871        public function widget( $args, $instance ) {
     872                global $comments, $comment;
     873
    828874                if ( ! isset( $args['widget_id'] ) )
    829875                        $args['widget_id'] = $this->id;
    830876
    831                 if ( isset( $cache[ $args['widget_id'] ] ) ) {
    832                         echo $cache[ $args['widget_id'] ];
     877                // Serve from cache if available.
     878                $cache = $this->get_widget_cache( $args['widget_id'] );
     879                if ( ! empty( $cache ) ) {
     880                        echo $cache;
    833881                        return;
    834882                }
    835883
     
    883931                $output .= '</ul>';
    884932                $output .= $args['after_widget'];
    885933
     934                $this->update_widget_cache( $args['widget_id'], $output );
    886935                echo $output;
    887 
    888                 if ( ! $this->is_preview() ) {
    889                         $cache[ $args['widget_id'] ] = $output;
    890                         wp_cache_set( 'widget_recent_comments', $cache, 'widget' );
    891                 }
    892936        }
    893937
    894938        public function update( $new_instance, $old_instance ) {