Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP + APC User Cache Entries Timeout Issue

Tags:

php

apc

cakephp

I'm using CakePHP (version 1.3.8) and APC (version 3.1.3p1) with these settings:

apc.ini

extension=apc.so
apc.enabled=1
apc.enable_cli=0
apc.shm_size=128
apc.stat=0
apc.num_files_hint=10000
apc.user_entries_hint=10000
apc.max_file_size=5
apc.user_ttl = 3600
apc.ttl = 3600

Cake Core Settings:

Cache::config('default', array(
        'engine' => 'Apc',
        'duration'=> '+5 minutes',
        'probability'=> 100,
        'prefix' => Inflector::slug(APP_DIR) . '_',
));

And for some reason, the timeout listed for the User Cache Entries (as viewed through mysite.com/apc.php) are all 86313600 seconds (999 days). I have no idea why it would be so high considering I've set both apc.user_ttl and apc.ttl in apc.ini and set the duration via Cake. I've tried clearing all of the APC caches and restarting Apache.

Any assistance would be much appreciated. Thanks.

Edit: thought it would be worth mentioning that the Runtime Settings shown through apc.php do have proper TTLs set as per the apc.ini config:

apc.cache_by_default: 1
apc.canonicalize: 1
apc.coredump_unmap: 0
apc.enable_cli: 0
apc.enabled: 1
apc.file_md5: 0
apc.file_update_protection: 2
apc.filters 
apc.gc_ttl: 3600
apc.include_once_override: 0
apc.lazy_classes: 0
apc.lazy_functions: 0
apc.max_file_size: 5
apc.mmap_file_mask  
apc.num_files_hint: 10000
apc.preload_path
apc.report_autofilter: 0
apc.rfc1867: 0
apc.rfc1867_freq: 0
apc.rfc1867_name: APC_UPLOAD_PROGRESS
apc.rfc1867_prefix: upload_
apc.rfc1867_ttl: 3600
apc.shm_segments: 1
apc.shm_size: 128
apc.stat: 0
apc.stat_ctime: 0
apc.ttl: 3600
apc.use_request_time: 1
apc.user_entries_hint: 10000
apc.user_ttl: 3600
apc.write_lock: 1
like image 352
Erebus Avatar asked Nov 12 '22 21:11

Erebus


1 Answers

I've figured out the issue, which ended up being confusion between what I think a "default" value should be and what CakePHP thinks a "default" value should be.

In cake/libs/cache.php, there is a write function which sets the key, value and duration of the cache entry, and passes it to the appropriate engine's write function (in this case APC). In this function it checks the cache config settings from core.php to see if you've specified a duration there. The code from core.php:

Cache::config('default', array(
    'engine' => 'Apc',
    'duration'=> 9000,
    'probability'=> 100,
    'prefix' => Inflector::slug(APP_DIR) . '_',
));

You can see that the first argument is the string 'default', which I assume means that the default value for all APC caching should use the following array, which includes a duration of 9000 seconds. However, in the aforementioned write function, it does a check for the instance's __name variable, which in the case of the cache entries, get set to "_cake_core_", instead of the default string value of "default". Shortly after, it goes to the config settings and looks for a value of "_cake_core_". Because this shouldn't be found (as I didn't set it explicitly), or if there was some value set by Cake it would be overridden by my default value (by my definition of default) it would rely on what I've set above. However, this isn't the case at all. In the __loadBoostrap function of cake/libs/configure.php:

if (Configure::read() >= 1) {
    $duration = '+10 seconds';
} else {
    $duration = '+999 days';
}

if (Cache::config('_cake_core_') === false) {
    Cache::config('_cake_core_', array_merge((array)$cache['settings'], array(
        'prefix' => $prefix . 'cake_core_', 'path' => $path . DS . 'persistent' . DS,
        'serialize' => true, 'duration' => $duration
    )));
}

So, if debug is set to 0 (which is what Configure::read() returns when it's not passed anything) and the config string is '_cake_core_' (like it is with my cache entries) it sets $duration to '+999 days', instead of the value I pass. The solution is to create another few lines in core.php like so:

Cache::config('_cake_core_', array(
    'engine' => 'Apc',
    'duration'=> 9000,
    'probability'=> 100,
    'prefix' => Inflector::slug(APP_DIR) . '_',
));

which overrides Cake's "default" or hard-coded value of 10 seconds or 999 days, depending on the debug value.

like image 132
Erebus Avatar answered Nov 15 '22 00:11

Erebus