New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Delete Cache by Group #2368
Delete Cache by Group #2368
Conversation
Co-authored-by: Jonny Harris <spacedmonkey@users.noreply.github.com>
added filter to allow plugin to adjust the called function
# Conflicts: # src/wp-includes/class-wp-object-cache.php # tests/phpunit/tests/cache.php
If this to live in core there needs to be a compat function found in core in cache-compat.php. This function would need to work for ALL object cache implementation, including and not limited to memcached. I personally think this is going be nearly impossible, as it is hard to know the implementation details of every object cache. But without that compatible layer, this can not live in core 😞 |
It's a FAQ and the suggested approch is using prefixes, which I believe |
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
…_groups' into INITS-115-Support_flushing_cache_groups
Please use remove test for |
If this is going to make it into core, then we are going to need some constant, like Thoughts? |
Reminds me of If we default to flushing the entire cache (in the compatibility method), can you give an example how and where |
I am not sure we do need the global WP_ALLOW_CACHE_GROUPS as I test for a flush_group function |
And flush all if flush_group not supported
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Revert debug changes.
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
src/wp-includes/cache-compat.php
Outdated
|
||
_doing_it_wrong( __FUNCTION__, __( 'Your implementation of object caching does not support flush by group.' ), '6.0.0' ); | ||
|
||
return wp_cache_flush(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a dangerous fallback for this method, having plugin code expecting to flush a specific cache group(s) and then flushing the entire cache is not going to end well.
Additionally, IMHO it's not a _doing_it_wrong()
E_USER_DEPRECATED
, possibly a E_USER_NOTICE
level warning instead though?
(I say this, because with many object caches, it's not possible to flush a specific group, as key-value stores often don't have a "flush keys with this prefix" - Memcache object cache dropin gets around this by prefixing the timestamp to keys, so that it can just switch to a new set of prefixes when flushed)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The worry here, is that if you call this function can expect and clear your group and it doesn't we need to warn developer this is happening. Maybe we should return a WP_Error
object?
So you could do this in your own code.
$result = wp_cache_flush_group( 'posts' );
if( is_wp_error( $result ) ) {
wp_cache_flush();
}
But give devs more control here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the WP_Error
approach.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think return false
would suffice myself if it wasn't going to flush everything.. "Clear this cache group, sorry, that failed.".
But as mentioned in #2368 (comment) variants whose cache server that don't support clearing by prefix, could rotate a prefix to flush the group.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that means that false, could mean a lot of things. Unsupported and the cache group flush failed. That is unclear for developers that using this function, why the failure.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some feedback from @felixarntz:
What I would suggest is considering making support of this more explicitly optional. For example
- Not put the
flush_group()
method in the base class, or alternatively put it in the base class as a no-op that just returnsfalse
.- Introduce
wp_cache_flush_group()
, but explicitly document it that it may not be supported and therefore returns a boolean to indicate success, which is critical to check here (other than maybe on other cache functions).- In the function, depending on my first point, either check if the method exists on the cache implementation and if not return
false
, or otherwise just call the method and return through its boolean result.Alternatively, we could make it even more explicit to clarify that developers need to be aware that this may not work, e.g. by having the boolean function just as a check that has to be explicitly called (e.g.
wp_cache_can_flush_group()
) before callingwp_cache_flush_group()
. The latter could cause a_doing_it_wrong()
if not supported or throw an exception.So TLDR whichever way we go, I definitely think it should be explicitly built and marked as optional.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@felixarntz's comments here reflect statement I have made throughout this code review. These needs to be a way for developers to know if running this function is going to work. They have to know if the object cache implement supports it.
I recommend adding a const, like WP_CACHE_SUPPORTS_GROUP_FLUSH
, so developers of object cache drop-ins can "opt-in" to support this feature. If this const is not defined, then, developers know not to use this function.
See these simplier examples.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest is using WP_OBJECTCACHE_*
since WP_CACHE
refers to WP's "page caching" mechanism.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a half thought in a Slack thread that I'll leave in full detail here so it doesn't get lost.
For a lot of groups currently, WP uses the last_changed
cache key to determine when the group was last changed. It acts as a faux group flushing mechanism.
wordpress-develop/src/wp-includes/post.php
Line 7406 in 8277055
wp_cache_set( 'last_changed', microtime(), 'posts' ); |
For drop-ins that support the flush_group()
method, WP could call that and trust the drop in developer to have checked their persistent cache supports it.
For drop-ins that do not include the method, WP could include something similar to polyfill the feature.
// Within caches
if ( ! method_exists( ... ) && 'wp_group_suffiixes' !== $group ) {
$group = $group . '::' . wp_cahce_group_suffix( $group );
}
// Function
function wp_cahce_group_suffix( $group, $update = false ) {
$suffix = wp_cache_get( $group, 'wp_group_suffiixes' );
if ( ! $update ) {
return $suffix;
}
$new_suffix = $suffix;
while ( $new_suffix === $suffix ) {
$new_suffix = wp_generate_password( 8, true, true );
}
return $new_suffix;
}
At this stage, I'd call this a thought bubble and it absolutely needs further thinking through. One of the issues Dion mentioned in Slack is that there is potential to hit key length issues in some persistent caches.
It's also possible this is a terrible idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the discussion for this ticket should move back to the original tickets. GH is a code review tool and not best designed for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new constant needs to be added to the beginning of src/wp-includes/cache.php
. I can't do that in the PR unfortunatly.
define( 'WP_OBJECT_CACHE_SUPPORTS_GROUP_FLUSH', false );
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
There seems to be unit tests failing now and coding standards need fixing. |
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
… file and set to false
$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' ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$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' ); | |
if (WP_OBJECT_CACHE_SUPPORTS_GROUP_FLUSH) { | |
$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' ); | |
} else { | |
$this->assertWPError( $results ); | |
$this->assertSame( 'unsupported', $results->get_error_code() ); | |
} |
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
Hello, What is the next step ? Do you need help for something ? |
@aksld The memcache object cache used by the tests needs support for this feature. Likely by using prefixes that increment. |
closed by #2969 |
Committed |
WordPress/performance#38
Trac ticket: https://core.trac.wordpress.org/ticket/4476