l3rady / object-cache-apcu

46 stars 17 forks source link

object-cache.php doesn’t work with WP abstraction layer #16

Closed nisbet-hubbard closed 3 months ago

nisbet-hubbard commented 3 months ago

The object-cache.php doesn’t seem to work with WP functions.

wp_get_cache_type() requires a class APC_Object_Cache to exist, for example: https://github.com/wp-cli/wp-cli/blob/f701f406aa39f6aeca2af16e92712780e2675bad/php/utils-wp.php#L297-L299

In WP CLI, although wp cache supports feature returns 0, wp cache get my_key can’t find any entry in APCu, and wp cache flush fails to flush any persistent cache shown in this plugin’s info panel.

Is this plugin supposed to be compatible with the WP abstraction layer?

l3rady commented 3 months ago

Not sure if you are confusing my object cache with someone else's?

The code you link is looking for this plugin: https://wordpress.org/extend/plugins/apc/ which is for APC which stopped being a thing back in PHP 5.3 days.

My object cache is for APCu and WP-CLI haven't updated their code to detect any APCu object caches. That is fine though as my object cache will just come up as unknown in their CLI commands.

wp cache flush fails to flush any persistent cache shown in this plugin’s info panel

My object cache isn't a plugin nor does it have an info panel so you must have some other plugin installed.

If you want to use my object cache you need to download it and manually place the object-cache.php file in the root of the WP_CONTENT_DIR which is usually ..... wp-content/object-cache.php

l3rady commented 3 months ago

Also I want to add, by default APCu is configured to not be enabled on the PHP CLI. So if it isn't enabled then any WP CLI function with apcu object cache will not work. Also if you are using a docker container to run wp-cli you may also find that a lot of the official docker containers for wp-cli don't come with apcu installed.

nisbet-hubbard commented 3 months ago

Many thanks for your response! I was looking at the plugin atec Cache APCu, which installs your object-cache.php. That’s why I mistakenly thought you were also the plugin’s author.

I was indeed referring to the unfortunate disconnect between the WP-CLI team and various authors of object-cache.php for APCu, and yes the detection doesn’t seem to make material difference.

The problem I have is as follows. With your wp-content/object-cache.php in place, running a WP-CLI command like wp cache flush or the function wp_cache_flush() doesn’t actually flush APCu cache. This can be verified by looking at a manually placed apc.php, which is available from the APCu repo. Similarly, other functions from the WP_Object_Cache class don’t seem to work: https://developer.wordpress.org/reference/classes/wp_object_cache/#persistent-cache-plugins.

PS Both APCu and PHP CLI are enabled on our machine; the problem also affects the underlying WP-wide functions, which are not unique to WP-CLI.

l3rady commented 3 months ago

Can you please send a screenshot of phpinfo for APCu section? Please also make sure https://www.php.net/manual/en/apcu.configuration.php#ini.apcu.enable-cli is = 1.

In the meantime I'm going to setup a local dev for apcu as I currently don't have one anymore as Ive moved to using redis as I need to scale horizontally.

nisbet-hubbard commented 3 months ago

This is what I have on hand… while I try to get the firewall working for phpinfo.

APCu Version 5.1.22 PHP Version 8.2.11

nisbet-hubbard commented 3 months ago
l3rady commented 3 months ago

Testing locally the object cache seems to be functioning fine for me:

image

Also a quick test with this:

add_action('init', function() {
    d(wp_cache_supports('get_multiple'));
    d(wp_cache_get_multiple(['1:site_name', '1:siteurl'], 'site-options'));
    d(wp_cache_flush());
    d(wp_cache_get_multiple(['1:site_name', '1:siteurl'], 'site-options'));
    die();
});

returns:

image

which is expected behaviour

l3rady commented 3 months ago

OK I think I might know what is going on here. From a quick search, PHP cli and PHP fpm don't share the same apcu memory so anything that the cli is doing wont see the same cache as the site using fpm. This might explain the issue also if @docjojo is having on their issue. If they are activating and deactivating plugins via wp cli then the website cache wont get updated.

nisbet-hubbard commented 3 months ago

Does what you’re saying also applies to calling wp_cache_flush() in other plugins? In our case, a caching plugin successfully runs the following code, but fails to get the APCu flushed:

function purge_object_cache() {

        if( !function_exists('wp_cache_flush') )
            return false;

        wp_cache_flush();

        $this->objects = $this->main_instance->get_objects();

        $this->objects['logs']->add_log('cache_controller::purge_object_cache', 'Purge object cache' );

        return true;

    }
l3rady commented 3 months ago

depends on how the plugin is calling that function.

E.G. if that plugin flushes cache on activation and the plugin is activated via wpcli then it wont work. It would only work from requests routed via php-fpm. Also this is assuming you are running a single instance of the site on one php-fpm pool.

l3rady commented 3 months ago

limitations of APCu and will explain why wp-cli havent bothered adding apcu support to their cli as its useless via the cli.

If the cli is important to you then I would recommend redis or memcached object cache instead.

docjojo commented 3 months ago

Hello Scott, I am not using the WP cli. Plugin activation/deactivatin in the WP backend / admin panel.

docjojo commented 3 months ago

@nisbet-hubbard

i am using this to flush

case 'APCu_Cache': if (function_exists('apcu_clear_cache')) $result=apcu_clear_cache(); break;

l3rady commented 3 months ago

Hello Scott, I am not using the WP cli. Plugin activation/deactivatin in the WP backend / admin panel.

Then I'm not sure what is causing your issue. I've tested and plugin activation and deactivation is working fine for me with apcu

l3rady commented 3 months ago

@nisbet-hubbard

i am using this to flush

case 'APCu_Cache': if (function_exists('apcu_clear_cache')) $result=apcu_clear_cache(); break;

If you are in WP land then you should just call wp_cache_flush() as that will take care of properly flushing whatever object caching is installed.

docjojo commented 3 months ago

why? because apcu_clear_cache() will also clear other APCu entries that are not WP related?

docjojo commented 3 months ago

i think it is an opcache issue, but i can not tell why.

may set Revalidate to 0 or 1? set string buffer to 0?

Version:    8.3.8
Max. files: 1000
String buffer (MB): 64
Revalidate (s): 60
Memory: 128 MB
Used:   128 MB
Items:  5,522
Hits:   931,760 (94.2%)
Misses: 57,256 (5.8%)
l3rady commented 3 months ago

i think it is an opcache issue, but i can not tell why.

may set Revalidate to 0 or 1? set string buffer to 0?

Version:  8.3.8
Max. files:   1000
String buffer (MB):   64
Revalidate (s):   60
Memory:   128 MB
Used: 128 MB
Items:    5,522
Hits: 931,760 (94.2%)
Misses:   57,256 (5.8%)

My opcache settings that don't present any issues for me:

  {
    echo 'zend_extension=opcache.so'
    echo 'opcache.enable={{PHP_OPCACHE_ENABLE}}'
    echo 'opcache.enable_cli=0'
    echo 'opcache.save_comments=1'
    echo 'opcache.interned_strings_buffer=8'
    echo 'opcache.fast_shutdown=1'
    echo 'opcache.validate_timestamps=1'
    echo 'opcache.revalidate_freq=2'
    echo 'opcache.use_cwd=1'
    echo 'opcache.max_accelerated_files=100000'
    echo 'opcache.max_wasted_percentage=5'
    echo 'opcache.memory_consumption={{PHP_OPCACHE_MEMORY_CONSUMPTION}}M'
    echo 'opcache.consistency_checks=0'
    echo 'opcache.huge_code_pages=1'
  } | tee /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
l3rady commented 3 months ago

why? because apcu_clear_cache() will also clear other APCu entries that are not WP related?

because you leave it up to the object cache to determine how to flush. In my object cache yes I am just flushing all but I could also easily have functionality that just purges the WP site cache and leaves any other cache alone in apcu.

docjojo commented 3 months ago

thank you. will set opcache settings any see whether that will solve the issue.

nisbet-hubbard commented 3 months ago

The explanation based on the difference between php cli and php fpm makes sense to me. I was using WP-CLI for debugging, but the plugin in question calls wp_cache_flush() under php fpm. This means I’d need to replicate what it does using php fpm too, like you did.

Also a quick test with this:

add_action('init', function() {
  d(wp_cache_supports('get_multiple'));
  d(wp_cache_get_multiple(['1:site_name', '1:siteurl'], 'site-options'));
  d(wp_cache_flush());
  d(wp_cache_get_multiple(['1:site_name', '1:siteurl'], 'site-options'));
  die();
});

Is this something one can place in functions.php (along with a definition of d())? I got Scrape key check failed. Please try again. trying to do this when object-cache.php is present.

l3rady commented 3 months ago

Yes can be put in theme functions file to test. replace d() with var_dump();

nisbet-hubbard commented 3 months ago

That works, thanks! I had to edit the theme file on command line as the GUI’s Scrape key check failed prevented me inserting the snippet.

Since this demonstrates your object-cache.php is working as intended, I’ll close the issue so the conversation about docjojo’s plugins can concentrate in the other thread.