Make WordPress Core


Ignore:
Timestamp:
08/31/2025 09:41:54 PM (13 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.