Make WordPress Core


Ignore:
Timestamp:
08/31/2025 09:41:54 PM (5 months ago)
Author:
spacedmonkey
Message:

Caching API: Use consistent cache keys for query groups.

Query-based caches are now improved by reusing cache keys. Previously, cache keys for query caches were generated using the last_changed value as part of the key. This meant that whenever last_changed was updated, all the previously cached values for the group became unreachable.

The new approach allows WordPress to replace previously cached results that are known to be stale. The previous approach relied on the object cache backend evicting stale keys which is done at various levels of efficiency.

To address this, the following new helper functions have been introduced:

  • wp_cache_get_salted
  • wp_cache_set_salted
  • wp_cache_get_multiple_salted
  • wp_cache_set_multiple_salted

These functions provide a consistent way to get/set query caches. Instead of using the last_changed value as part of the cache key, it is now stored inside the cache value as a "salt". This allows cache keys to be reused, with values updated in place rather than relying on eviction of outdated entries.

Props spacedmonkey, peterwilsoncc, flixos90, sanchothefat, tillkruess, rmccue, mukesh27, adamsilverstein, owi, nickchomey.

File:
1 edited

Legend:

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

    r59542 r60697  
    831831            $cache_key     = $this->generate_cache_key( $qv, $this->request );
    832832            $cache_group   = 'user-queries';
     833            $last_changed  = $this->get_cache_last_changed( $qv );
     834
    833835            if ( $qv['cache_results'] ) {
    834                 $cache_value = wp_cache_get( $cache_key, $cache_group );
     836                $cache_value = wp_cache_get_salted( $cache_key, $cache_group, $last_changed );
    835837            }
    836838            if ( false !== $cache_value ) {
     
    867869                        'total_users' => $this->total_users,
    868870                    );
    869                     wp_cache_add( $cache_key, $cache_value, $cache_group );
     871                    wp_cache_set_salted( $cache_key, $cache_value, $cache_group, $last_changed );
    870872                }
    871873            }
     
    10441046     *
    10451047     * @since 6.3.0
     1048     * @since 6.9.0 The `$args` parameter was deprecated and renamed to `$deprecated`.
    10461049     *
    10471050     * @global wpdb $wpdb WordPress database abstraction object.
    10481051     *
    1049      * @param array  $args Query arguments.
    1050      * @param string $sql  SQL statement.
     1052     * @param array  $deprecated Unused.
     1053     * @param string $sql        SQL statement.
    10511054     * @return string Cache key.
    10521055     */
    1053     protected function generate_cache_key( array $args, $sql ) {
     1056    protected function generate_cache_key( array $deprecated, $sql ) {
    10541057        global $wpdb;
    10551058
     
    10571060        $sql = $wpdb->remove_placeholder_escape( $sql );
    10581061
    1059         $key          = md5( $sql );
    1060         $last_changed = wp_cache_get_last_changed( 'users' );
     1062        $key = md5( $sql );
     1063
     1064        return "get_users:$key";
     1065    }
     1066
     1067    /**
     1068     * Retrieves the last changed cache timestamp for users and optionally posts.
     1069     *
     1070     * @since 6.9.0
     1071     *
     1072     * @param array $args Query arguments.
     1073     * @return string[] The last changed timestamp string for the relevant cache groups.
     1074     */
     1075    protected function get_cache_last_changed( array $args ) {
     1076        $last_changed = (array) wp_cache_get_last_changed( 'users' );
    10611077
    10621078        if ( empty( $args['orderby'] ) ) {
     
    10811097            }
    10821098
    1083             $last_changed .= wp_cache_get_last_changed( 'posts' );
     1099            $last_changed[] = wp_cache_get_last_changed( 'posts' );
    10841100
    10851101            if ( $switch ) {
     
    10881104        }
    10891105
    1090         return "get_users:$key:$last_changed";
     1106        return $last_changed;
    10911107    }
    10921108
Note: See TracChangeset for help on using the changeset viewer.