Skip to content

Commit

Permalink
Cache API: Add wp_cache_flush_group function.
Browse files Browse the repository at this point in the history
Add a new plugable function called `wp_cache_flush_group`, that will allow developers to clear whole cache groups with a single call. Developers can detect if their current implementation of an object cache supports flushing by group, by calling `wp_cache_supports_group_flush` which returns true if it is supported. If the developers of the object cache drop-in has not implemented `wp_cache_flush_group` and `wp_cache_supports_group_flush`, these functions are polyfilled and `wp_cache_supports_group_flush` defaults to false.

Props Spacedmonkey, filosofo, ryan, sc0ttkclark, SergeyBiryukov, scribu, Ste_95, dd32, dhilditch, dougal, lucasbustamante, dg12345, tillkruess, peterwilsoncc, flixos90, pbearne.
Fixes #4476.

git-svn-id: https://develop.svn.wordpress.org/trunk@53763 602fd350-edb4-49c9-b593-d223f7449a82
  • Loading branch information
spacedmonkey committed Jul 22, 2022
1 parent bd151a9 commit 40768e4
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/wp-includes/cache-compat.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,49 @@ function wp_cache_flush_runtime() {
return wp_using_ext_object_cache() ? false : wp_cache_flush();
}
endif;

if ( ! function_exists( 'wp_cache_flush_group' ) ) :
/**
* Removes all cache items in a group, if the object cache implementation supports it.
* Before calling this method, always check for group flushing support using the
* `wp_cache_supports_group_flush()` method.
*
* @since 6.1.0
*
* @see WP_Object_Cache::flush_group()
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
*
* @param string $group Name of group to remove from cache.
* @return bool True if group was flushed, false otherwise.
*/
function wp_cache_flush_group( $group ) {
global $wp_object_cache;

if ( ! wp_cache_supports_group_flush() ) {
_doing_it_wrong(
__FUNCTION__,
__( 'Your object cache implementation does not support flushing individual groups.' ),
'6.1.0'
);

return false;
}

return $wp_object_cache->flush_group( $group );
}
endif;

if ( ! function_exists( 'wp_cache_supports_group_flush' ) ) :
/**
* Whether the object cache implementation supports flushing individual cache groups.
*
* @since 6.1.0
*
* @see WP_Object_Cache::flush_group()
*
* @return bool True if group flushing is supported, false otherwise.
*/
function wp_cache_supports_group_flush() {
return false;
}
endif;
32 changes: 32 additions & 0 deletions src/wp-includes/cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,19 @@ function wp_cache_init() {
$GLOBALS['wp_object_cache'] = new WP_Object_Cache();
}

/**
* Whether the object cache implementation supports flushing individual cache groups.
*
* @since 6.1.0
*
* @see WP_Object_Cache::flush_group()
*
* @return bool True if group flushing is supported, false otherwise.
*/
function wp_cache_supports_group_flush() {
return true;
}

/**
* Adds data to the cache, if the cache key doesn't already exist.
*
Expand Down Expand Up @@ -281,6 +294,25 @@ function wp_cache_flush_runtime() {
return wp_cache_flush();
}

/**
* Removes all cache items in a group, if the object cache implementation supports it.
* Before calling this method, always check for group flushing support using the
* `wp_cache_supports_group_flush()` method.
*
* @since 6.1.0
*
* @see WP_Object_Cache::flush_group()
* @global WP_Object_Cache $wp_object_cache Object cache global instance.
*
* @param string $group Name of group to remove from cache.
* @return bool True if group was flushed, false otherwise.
*/
function wp_cache_flush_group( $group ) {
global $wp_object_cache;

return $wp_object_cache->flush_group( $group );
}

/**
* Closes the cache.
*
Expand Down
14 changes: 14 additions & 0 deletions src/wp-includes/class-wp-object-cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,20 @@ public function set_multiple( array $data, $group = '', $expire = 0 ) {
return $values;
}

/**
* Removes all cache items in a group.
*
* @since 6.1.0
*
* @param string $group Name of group to remove from cache.
* @return true Always returns true.
*/
public function flush_group( $group ) {
unset( $this->cache[ $group ] );

return true;
}

/**
* Retrieves the cache contents, if it exists.
*
Expand Down
11 changes: 11 additions & 0 deletions tests/phpunit/includes/object-cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -745,6 +745,17 @@ function wp_cache_init() {
$wp_object_cache = new WP_Object_Cache();
}

/**
* Whether the object cache implementation supports flushing individual cache groups.
*
* @since 6.1.0
*
* @return bool True if group flushing is supported, false otherwise.
*/
function wp_cache_supports_group_flush() {
return false;
}

/**
* Adds a group or set of groups to the list of non-persistent groups.
*
Expand Down
32 changes: 32 additions & 0 deletions tests/phpunit/tests/cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,4 +415,36 @@ public function test_wp_cache_delete_multiple() {

$this->assertSame( $expected, $found );
}

/**
* @ticket 4476
* @ticket 9773
*
* test wp_cache_flush_group
*
* @covers ::wp_cache_flush_group
*/
public function test_wp_cache_flush_group() {
$key = 'my-key';
$val = 'my-val';

wp_cache_set( $key, $val, 'group-test' );
wp_cache_set( $key, $val, 'group-kept' );

$this->assertSame( $val, wp_cache_get( $key, 'group-test' ), 'test_wp_cache_flush_group: group-test should contain my-val' );

if ( wp_using_ext_object_cache() ) {
$this->setExpectedIncorrectUsage( 'wp_cache_flush_group' );
}

$results = wp_cache_flush_group( 'group-test' );

if ( wp_using_ext_object_cache() ) {
$this->assertFalse( $results );
} else {
$this->assertTrue( $results );
$this->assertFalse( wp_cache_get( $key, 'group-test' ), 'test_wp_cache_flush_group: group-test should return false' );
$this->assertSame( $val, wp_cache_get( $key, 'group-kept' ), 'test_wp_cache_flush_group: group-kept should still contain my-val' );
}
}
}
2 changes: 2 additions & 0 deletions tests/phpunit/tests/pluggable.php
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ public function get_pluggable_function_signatures() {

// wp-includes/cache.php:
'wp_cache_init' => array(),
'wp_cache_supports_group_flush' => array(),
'wp_cache_add' => array(
'key',
'data',
Expand Down Expand Up @@ -327,6 +328,7 @@ public function get_pluggable_function_signatures() {
),
'wp_cache_flush' => array(),
'wp_cache_flush_runtime' => array(),
'wp_cache_flush_group' => array( 'group' ),
'wp_cache_close' => array(),
'wp_cache_add_global_groups' => array( 'groups' ),
'wp_cache_add_non_persistent_groups' => array( 'groups' ),
Expand Down

0 comments on commit 40768e4

Please sign in to comment.