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/cache-compat.php

    r54448 r60697  
    200200    }
    201201endif;
     202
     203if ( ! function_exists( 'wp_cache_get_salted' ) ) :
     204    /**
     205     * Retrieves cached data if valid and unchanged.
     206     *
     207     * @since 6.9.0
     208     *
     209     * @param string          $cache_key The cache key used for storage and retrieval.
     210     * @param string          $group     The cache group used for organizing data.
     211     * @param string|string[] $salt      The timestamp (or multiple timestamps if an array) indicating when the cache group(s) were last updated.
     212     * @return mixed|false The cached data if valid, or false if the cache does not exist or is outdated.
     213     */
     214    function wp_cache_get_salted( $cache_key, $group, $salt ) {
     215        $salt  = is_array( $salt ) ? implode( ':', $salt ) : $salt;
     216        $cache = wp_cache_get( $cache_key, $group );
     217
     218        if ( ! is_array( $cache ) ) {
     219            return false;
     220        }
     221
     222        if ( ! isset( $cache['salt'] ) || ! isset( $cache['data'] ) || $salt !== $cache['salt'] ) {
     223            return false;
     224        }
     225
     226        return $cache['data'];
     227    }
     228endif;
     229
     230if ( ! function_exists( 'wp_cache_set_salted' ) ) :
     231    /**
     232     * Stores salted data in the cache.
     233     *
     234     * @since 6.9.0
     235     *
     236     * @param string          $cache_key The cache key under which to store the data.
     237     * @param mixed           $data      The data to be cached.
     238     * @param string          $group     The cache group to which the data belongs.
     239     * @param string|string[] $salt      The timestamp (or multiple timestamps if an array) indicating when the cache group(s) were last updated.
     240     * @param int             $expire    Optional. When to expire the cache contents, in seconds.
     241     *                                   Default 0 (no expiration).
     242     * @return bool True on success, false on failure.
     243     */
     244    function wp_cache_set_salted( $cache_key, $data, $group, $salt, $expire = 0 ) {
     245        $salt = is_array( $salt ) ? implode( ':', $salt ) : $salt;
     246        return wp_cache_set(
     247            $cache_key,
     248            array(
     249                'data' => $data,
     250                'salt' => $salt,
     251            ),
     252            $group,
     253            $expire
     254        );
     255    }
     256endif;
     257
     258if ( ! function_exists( 'wp_cache_get_multiple_salted' ) ) :
     259    /**
     260     * Retrieves multiple items from the cache, only considering valid and unchanged items.
     261     *
     262     * @since 6.9.0
     263     *
     264     * @param array           $cache_keys Array of cache keys to retrieve.
     265     * @param string          $group      The group of the cache to check.
     266     * @param string|string[] $salt       The timestamp (or multiple timestamps if an array) indicating when the cache group(s) were last updated.
     267     * @return array An associative array containing cache values. Values are `false` if they are not found or outdated.
     268     */
     269    function wp_cache_get_multiple_salted( $cache_keys, $group, $salt ) {
     270        $salt  = is_array( $salt ) ? implode( ':', $salt ) : $salt;
     271        $cache = wp_cache_get_multiple( $cache_keys, $group );
     272
     273        foreach ( $cache as $key => $value ) {
     274            if ( ! is_array( $value ) ) {
     275                $cache[ $key ] = false;
     276                continue;
     277            }
     278            if ( ! isset( $value['salt'], $value['data'] ) || $salt !== $value['salt'] ) {
     279                $cache[ $key ] = false;
     280                continue;
     281            }
     282            $cache[ $key ] = $value['data'];
     283        }
     284
     285        return $cache;
     286    }
     287endif;
     288
     289if ( ! function_exists( 'wp_cache_set_multiple_salted' ) ) :
     290    /**
     291     * Stores multiple pieces of salted data in the cache.
     292     *
     293     * @since 6.9.0
     294     *
     295     * @param mixed           $data   Data to be stored in the cache for all keys.
     296     * @param string          $group  Group to which the cached data belongs.
     297     * @param string|string[] $salt   The timestamp (or multiple timestamps if an array) indicating when the cache group(s) were last updated.
     298     * @param int             $expire Optional. When to expire the cache contents, in seconds.
     299     *                                Default 0 (no expiration).
     300     * @return bool[] Array of return values, grouped by key. Each value is either
     301     *                true on success, or false on failure.
     302     */
     303    function wp_cache_set_multiple_salted( $data, $group, $salt, $expire = 0 ) {
     304        $salt      = is_array( $salt ) ? implode( ':', $salt ) : $salt;
     305        $new_cache = array();
     306        foreach ( $data as $key => $value ) {
     307            $new_cache[ $key ] = array(
     308                'data' => $value,
     309                'salt' => $salt,
     310            );
     311        }
     312        return wp_cache_set_multiple( $new_cache, $group, $expire );
     313    }
     314endif;
Note: See TracChangeset for help on using the changeset viewer.