Skip to:
Content

bbPress.org


Ignore:
Timestamp:
11/24/2019 01:17:27 AM (5 years ago)
Author:
johnjamesjacoby
Message:

Engagements: add caching to User strategy, for 2.5 compatibility.

This commit re-adds query caching for FIND_IN_SET queries, fixing long pageloads on sites with large amounts of usermeta that are unable to run the 2.6 database upgrade routine(s).

Props johnjamesjacoby, netweb. Fixes #3292. For 2.7, trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/includes/common/engagements.php

    r6876 r6993  
    528528 * User strategy for interfacing with User Engagements
    529529 *
     530 * This strategy largely exists for backwards compatibility with bbPress 2.5,
     531 * or installations that have not upgraded their databases to 2.6 or above.
     532 *
     533 * Note: this strategy is going to be a bit less tidy than the others, because
     534 * it needs to do weird things to maintain the 2.5 status-quo. Do not use this
     535 * strategy as an example when building your own.
     536 *
    530537 * @since 2.6.0 bbPress (r6844)
    531538 */
     
    569576
    570577                // Forums & Topics used different keys :/
    571                 $key       = ( bbp_get_forum_post_type() === $post_type )
     578                $key = ( bbp_get_forum_post_type() === $post_type )
    572579                    ? '_bbp_forum_subscriptions'
    573580                    : '_bbp_subscriptions';
     
    588595        // Return the old (pluralized) user option key
    589596        return $key;
     597    }
     598
     599    /**
     600     * Private function to get a 2.5 compatible cache key.
     601     *
     602     * This method exists to provide backwards compatibility with bbPress 2.5,
     603     * which had caching surrounding the FIND_IN_SET usermeta queries.
     604     *
     605     * @since 2.6.3 bbPress (r6991)
     606     *
     607     * @param string $meta_key
     608     * @param int    $object_id
     609     *
     610     * @return string
     611     */
     612    private function get_cache_key( $meta_key = '', $object_id = 0 ) {
     613
     614        // Maybe guess at post type
     615        $post_type = ! empty( $object_id )
     616            ? get_post_type( $object_id )
     617            : bbp_get_topic_post_type();
     618
     619        switch ( $meta_key ) {
     620
     621            // Favorites
     622            case '_bbp_favorite' :
     623                $key = 'bbp_get_topic_favoriters_';
     624                break;
     625
     626            // Subscriptions
     627            case '_bbp_subscription' :
     628
     629                // Forums & Topics used different keys :/
     630                $key = ( bbp_get_forum_post_type() === $post_type )
     631                    ? 'bbp_get_forum_subscribers_'
     632                    : 'bbp_get_topic_subscribers_';
     633
     634                break;
     635
     636            // Unknown, so pluralize
     637            default :
     638                $nounize = rtrim( $meta_key, 'e' );
     639                $key     = "bbp_get_{$post_type}_{$nounize}ers_";
     640                break;
     641        }
     642
     643        // Return the old (pluralized) user option key
     644        return $key;
     645    }
     646
     647    /**
     648     * Get the user engagement cache for a given meta key and object ID.
     649     *
     650     * This method exists to provide backwards compatibility with bbPress 2.5,
     651     * which had caching surrounding the FIND_IN_SET queries in usermeta.
     652     *
     653     * @since 2.6.3 bbPress (r6991)
     654     *
     655     * @param string $meta_key
     656     * @param int    $object_id
     657     *
     658     * @return mixed Results from cache get
     659     */
     660    private function cache_get( $meta_key = '', $object_id = 0 ) {
     661        $cache_key = $this->get_cache_key( $meta_key, $object_id );
     662
     663        return wp_cache_get( $cache_key, 'bbpress_users' );
     664    }
     665
     666    /**
     667     * Set the user engagement cache for a given meta key and object ID.
     668     *
     669     * This method exists to provide backwards compatibility with bbPress 2.5,
     670     * which had caching surrounding the FIND_IN_SET queries in usermeta.
     671     *
     672     * @since 2.6.3 bbPress (r6991)
     673     *
     674     * @param string $meta_key
     675     * @param int    $object_id
     676     *
     677     * @return mixed Results from cache set
     678     */
     679    private function cache_set( $meta_key = '', $object_id = 0, $user_ids = array() ) {
     680        $cache_key = $this->get_cache_key( $meta_key, $object_id );
     681        $user_ids  = $this->parse_comma_list( $user_ids );
     682
     683        return wp_cache_set( $cache_key, $user_ids, 'bbpress_users' );
     684    }
     685
     686    /**
     687     * Delete the user engagement cache for a given meta key and object ID.
     688     *
     689     * This method exists to provide backwards compatibility with bbPress 2.5,
     690     * which had caching surrounding the FIND_IN_SET queries in usermeta.
     691     *
     692     * @since 2.6.3 bbPress (r6991)
     693     *
     694     * @param string $meta_key
     695     * @param int    $object_id
     696     *
     697     * @return mixed Results from cache delete
     698     */
     699    private function cache_delete( $meta_key = '', $object_id = 0 ) {
     700        $cache_key = $this->get_cache_key( $meta_key, $object_id );
     701
     702        return wp_cache_delete( $cache_key, 'bbpress_users' );
    590703    }
    591704
     
    626739            $object_ids   = implode( ',', $this->parse_comma_list( $object_ids ) );
    627740            $retval       = update_user_option( $user_id, $option_key, $object_ids );
     741
     742            // Delete cache, if successful
     743            if ( true === $retval ) {
     744                $this->cache_delete( $meta_key, $object_id );
     745            }
    628746        }
    629747
     
    658776                ? update_user_option( $user_id, $option_key, $object_ids )
    659777                : delete_user_option( $user_id, $option_key );
     778
     779            // Delete cache, if successful
     780            if ( true === $retval ) {
     781                $this->cache_delete( $meta_key, $object_id );
     782            }
    660783        }
    661784
     
    676799     */
    677800    public function remove_user_from_all_objects( $user_id = 0, $meta_key = '', $meta_type = 'post' ) {
     801
     802        // Get the key
    678803        $option_key = $this->get_user_option_key( $meta_key );
    679         return delete_user_option( $user_id, $option_key );
     804
     805        // Get the option
     806        $object_ids = $this->parse_comma_list( get_user_option( $option_key, $user_id ) );
     807
     808        // Attempt to delete the
     809        $retval = delete_user_option( $user_id, $option_key );
     810
     811        // Try to delete caches, but only if everything else succeeded
     812        if ( ! empty( $retval ) && ! empty( $object_ids ) ) {
     813            foreach( $object_ids as $object_id ) {
     814                $this->cache_delete( $meta_key, $object_id );
     815            }
     816        }
     817
     818        // Return true if user was removed, or false if not
     819        return $retval;
    680820    }
    681821
     
    745885            // Loop through users and remove their user options
    746886            foreach ( $user_ids as $user_id ) {
    747                 $removed[] = delete_user_option( $user_id, $option_key );
     887                $removed[] = $this->remove_user_from_all_objects( $user_id, $meta_key );
    748888            }
    749889
     
    771911     */
    772912    public function get_users_for_object( $object_id = 0, $meta_key = '', $meta_type = 'post' ) {
    773         $option_key = $this->get_user_option_key( $meta_key, $object_id, true );
    774         $bbp_db     = bbp_db();
    775         $user_ids   = $bbp_db->get_col( "SELECT user_id FROM {$bbp_db->usermeta} WHERE meta_key = '{$option_key}' and FIND_IN_SET('{$object_id}', meta_value) > 0" );
    776 
    777         return wp_parse_id_list( $user_ids );
     913
     914        // Try to get user IDs from cache
     915        $user_ids = $this->cache_get( $meta_key, $object_id );
     916
     917        // Cache is empty, so hit the database
     918        if ( false === $user_ids ) {
     919            $option_key = $this->get_user_option_key( $meta_key, $object_id, true );
     920            $bbp_db     = bbp_db();
     921            $user_ids   = $bbp_db->get_col( "SELECT user_id FROM {$bbp_db->usermeta} WHERE meta_key = '{$option_key}' and FIND_IN_SET('{$object_id}', meta_value) > 0" );
     922
     923            // Always cache results (even if empty, to prevent multiple misses)
     924            $this->cache_set( $meta_key, $object_id, $user_ids );
     925        }
     926
     927        // Return parsed IDs
     928        return $this->parse_comma_list( $user_ids );
    778929    }
    779930
Note: See TracChangeset for help on using the changeset viewer.