Unexpected output: Affected paths: relative - resubmit patch.
⚙ D443 INP-1838 - Set expiration limit for life-time cached keys
Page MenuHomeIn-Portal Phabricator

INP-1838 - Set expiration limit for life-time cached keys
ClosedPublic

Authored by alex on Feb 16 2023, 11:23 AM.

Details

Test Plan

Memcache caching

How to calculate infinite expiration timestamp on Memcached 1.4.15

  1. open SSH connection to a web server (or where the Memcache is installed)
  2. run this command:
(sleep 1; echo "stats"; sleep 1; echo "quit";) | telnet localhost 11211 | grep 'time'

Example output:

STAT uptime 61335
STAT time 1676435743
  1. subtract the number after the uptime word from the number after the time word (e.g. 1676435743 - 61335 = 1676374408) and remember this number

How to calculate infinite expiration timestamp on Memcached 1.6.15

  1. No need to calculate because it's always 0.

How to determine key expiration

  1. open SSH connection to a web server (or where the Memcache is installed)
  2. run this command (replace slab_number_here with a positive number starting from 1; replace key_name_here with a key name you want to get info about):
(sleep 1; echo "stats cachedump slab_number_here 0"; sleep 1; echo "quit";) | telnet localhost 11211 | grep 'key_name_here'

Example output:

ITEM key_name_here [value_here b; timestamp_here s]
  1. if no data is returned try incrementing the number used in place of the slab_number_here text by 1 and running that command again
  2. if the number in place of the timestamp_here text the infinite expiration timestamp (either 0 or above calculated), then the key will never expire
  3. otherwise the key will expire at the given date/time

How to determine every key expiration/presence in the cache

  1. same steps as above, but omit the | grep 'key_name_here' part of the command
  2. iterate all slab numbers until no data between Escape character is '^]'. and END lines is returned

How to clean the cache

  1. if you have CentOS, then run the systemctl restart memcached.service command as the root user on the server
  2. when testing on the Memcache PHP extension (not Memcached PHP extension) please refresh Admin Console (the login will do) to initialize the Memcache, because otherwise, it won't work properly

Database caching

How to determine key expiration

  1. open the database (e.g. via phpMyAdmin)
  2. execute the SELECT LifeTime FROM SystemCache WHERE VarName = 'key_name_here'; database query
  3. if you'll get -1 it means, that the key won't automatically expire
  4. if you'll get a timestamp it means, that the key will expire after that time

How to determine every key expiration/presence in the cache

  1. same steps as above, but omit the WHERE VarName = 'key_name_here' part of the database query

How to clean the cache

  1. open the database (e.g. via phpMyAdmin)
  2. run the TRUNCATE SystemCache; database query in the

Actual tests

Testing clean install

  1. perform a clean install via the /core/install.php script
  2. confirm, that at the System Configuration installation step the Maximum Cache Duration (in days) setting has an initial value of 30
  3. change value to 25 and proceed with the install
  4. confirm, that after the installation was done the MaxCacheDuration setting in the /system/config.php has a value of 25

Testing an upgrade

  1. remove the $_CONFIG['Misc']['MaxCacheDuration'] = ...; line in the /system/config.php file
  2. open the /core/install.php script of the existing In-Portal installation
  3. on the Installation Maintenance screen:
    • type root user login/password
    • select the Upgrade In-Portal radio button
    • press Continue
  4. perform the upgrade
  5. confirm, that after the installation was done the MaxCacheDuration setting in the /system/config.php has a value of 30

Testing "setCache"

NOTE: Repeat with CacheHandler set to Memcached as well.

Setup:

  • clean the memory cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Memcache

Set without expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteCache('key_with_def_exp');
$application->setCache('key_with_def_exp', 'v1');
  • confirm (see instructions above), that the "key_with_def_exp" key has an expiration of 25 days (from the time key was set via the "setCache" method call)

Set with expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteCache('key_with_exp');
$application->setCache('key_with_exp', 'v2', 3600);
  • confirm (see instructions above), that the "key_with_exp" key has an expiration of 1 hour (from the time key was set via the "setCache" method call)

Set with infinite expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteCache('key_with_inf_exp');
$application->setCache('key_with_inf_exp', 'v2', 0);
  • confirm (see instructions above), that the "key_with_inf_exp" key has an infinite expiration

Testing "addCache"

NOTE: Repeat with CacheHandler set to Memcached as well.

Setup:

  • clean the memory cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Memcache

Add without expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteCache('key_with_def_exp');
$application->addCache('key_with_def_exp', 'v1');
  • confirm (see instructions above), that the "key_with_def_exp" key has an expiration of 25 days (from the time key was set via the "addCache" method call)

Add with expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteCache('key_with_exp');
$application->addCache('key_with_exp', 'v2', 3600);
  • confirm (see instructions above), that the "key_with_exp" key has an expiration of 1 hour (from the time key was set via the "addCache" method call)

Add with infinite expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteCache('key_with_inf_exp');
$application->addCache('key_with_inf_exp', 'v2', 0);
  • confirm (see instructions above), that the "key_with_inf_exp" key an infinite expiration

Add won't overwrite:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->addCache('key_with_exp', 'v3', 86400);
echo $application->getCache('key_with_exp');
  • confirm, that both key value (that is shown on screen) and expiration (see instructions above) match $application->addCache('key_with_exp', 'v2', 3600); command executed above this test

Testing "setDBCache"

Setup:

  • clean the database cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Fake

Set without expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteDBCache('db_key_with_def_exp');
$application->setDBCache('db_key_with_def_exp', 'v1');
  • confirm (see instructions above), that "db_key_with_def_exp" key has expiration of 25 days (from the the time key was set via "setDBCache" method call)

Set with expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteDBCache('db_key_with_exp');
$application->setDBCache('db_key_with_exp', 'v2', 3600);
  • confirm (see instructions above), that "db_key_with_exp" key has expiration of 1 hour (from the the time key was set via "setDBCache" method call)

Set with infinite expiration:

  • replace code fragment between $application->Init(); and $application->Done(); in the /index.php file with this code:
$application->deleteDBCache('db_key_with_inf_exp');
$application->setDBCache('db_key_with_inf_exp', 'v2', 0);
  • confirm (see instructions above), that "db_key_with_inf_exp" key has in infinite expiration

Testing internal caches expiration for Memcache

NOTE: Repeat with CacheHandler set to Memcached as well.

Setup:

  • clean the memory cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Memcache

Populate cache:

  • login to In-Portal admin console
  • open any category record for editing (to populate master:StructureTree key)
  • make some changes
  • save changed record to the database (to set category serial key)
  • visit the Front-End in another web browser tab (to populate master:template_mapping, master:cms_menu and master:domains_parsed keys)

Confirm, that:

  • these keys have infinite expiration (the 1738250904 number might differ on your install):
    • test
    • site_serial:1738250904
    • site_serial:1738250904:1:master:configs_parsed
    • site_serial:1738250904:1:master:last_cache_rebuild
    • site_serial:1738250904:1:master:StructureTree
    • site_serial:1738250904:1:master:template_mapping
    • site_serial:1738250904:1:master:cms_menu
    • site_serial:1738250904:1:master:sections_parsed
    • site_serial:1738250904:1:master:domains_parsed
    • site_serial:1738250904:1:master:config_files
  • all other keys have an expiration of 25 days (with a few seconds margin) relative to the time they're set

Testing internal caches expiration for DB cache

Setup:

  • clean the memory cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Fake

Populate cache:

  • login to In-Portal admin console
  • open any category record for editing (to populate StructureTree key)
  • make some changes
  • save the changed record to the database (to set category serial key)
  • visit the Front-End in another web browser tab (to populate template_mapping, cms_menu and domains_parsed keys)

Confirm, that:

  • these keys have infinite expiration:
    • configs_parsed
    • last_cache_rebuild
    • StructureTree
    • template_mapping
    • cms_menu
    • sections_parsed
    • domains_parsed
    • config_files
  • the keys, that end with _HotLimit (e.g. Topic_HotLimit) have 3600 expiration
  • if some keys start with ShippingQuotes, then they should have 1 day expiration

Testing template fragment caching in Memcache has an expiration cap

NOTE: Repeat with CacheHandler set to Memcached as well.

Setup:

  • clean the memory cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Memcache

Populate cache:

  1. login to the Admin Console
  2. go to the ConfigurationWebsiteAdvanced section
  3. enable the Enable Tag Caching system setting
  4. save changes
  5. open the Front-End

Confirm, that:

  • site_serial:1738250904:1:parser_35334543 like keys (all numbers may vary) are present
  • they have an expiration of 25 days (with a few seconds margin) relative to the time they're set (page, that was setting them on the Front-End was accessed)

Testing template fragment caching in Memcache can configure expiration

NOTE: Repeat with CacheHandler set to Memcached as well.

Setup:

  • clean the memory cache (see instructions above)
  • change the value of the MaxCacheDuration setting in the /system/config.php file to the 25
  • change the value of the CacheHandler setting in the /system/config.php file to the Memcache

Populate cache:

  1. change <inp2:m_Cache key="prefix:lang;skip_var:t,page,per_page,sort_by"> line in the themes/advanced/platform/elements/header.elm.tpl template to <inp2:m_Cache key="prefix:lang;skip_var:t,page,per_page,sort_by" cache_timeout="3600">
  2. login to the Admin Console
  3. go to the ConfigurationWebsiteAdvanced section
  4. enable the Enable Tag Caching system setting
  5. save changes
  6. open the Front-End

Confirm, that:

  • site_serial:1738250904:1:parser_35334543 like keys (all numbers may vary) are present
  • they some of them now have an expiration of 1 hour (with a few seconds margin) relative to the time they're set (page, that was setting them on the Front-End was accessed)

Diff Detail

Repository
rINP In-Portal
Branch
/in-portal/branches/5.2.x
Lint
Lint ErrorsExcuse: Haven't introduced any new issues.
SeverityLocationCodeMessage
Errorcore/kernel/managers/cache_manager.php:356PHPCS.E.CodingStandard.WhiteSpace.ControlStructureSpacing.SpaceBeforeCloseBraceCodingStandard.WhiteSpace.ControlStructureSpacing.SpaceBeforeCloseBrace
Errorcore/kernel/managers/cache_manager.php:356PHPCS.E.CodingStandard.WhiteSpace.ControlStructureSpacing.SpacingAfterOpenBraceCodingStandard.WhiteSpace.ControlStructureSpacing.SpacingAfterOpenBrace
Errorcore/kernel/managers/cache_manager.php:709PHPCS.E.CodingStandard.NamingConventions.ValidFunctionName.PublicUnderscoreCodingStandard.NamingConventions.ValidFunctionName.PublicUnderscore
Errorcore/kernel/nparser/nparser.php:973PHPCS.E.CodingStandard.Commenting.FunctionComment.MissingCodingStandard.Commenting.FunctionComment.Missing
Errorcore/kernel/nparser/nparser.php:973PHPCS.E.Squiz.Scope.MethodScope.MissingSquiz.Scope.MethodScope.Missing
Errorcore/kernel/nparser/nparser.php:984PHPCS.E.CodingStandard.Commenting.InlineComment.NotCapitalCodingStandard.Commenting.InlineComment.NotCapital
Errorcore/kernel/utility/cache.php:117PHPCS.E.Generic.Files.LineLength.MaxExceededGeneric.Files.LineLength.MaxExceeded
Errorcore/kernel/utility/cache.php:172PHPCS.E.Squiz.Scope.MethodScope.MissingSquiz.Scope.MethodScope.Missing
Errorcore/kernel/utility/cache.php:217PHPCS.E.Squiz.Scope.MethodScope.MissingSquiz.Scope.MethodScope.Missing
Errorcore/kernel/utility/cache.php:501PHPCS.E.CodingStandard.Commenting.InlineComment.InvalidEndCharCodingStandard.Commenting.InlineComment.InvalidEndChar
Errorcore/kernel/utility/cache.php:501PHPCS.E.CodingStandard.Commenting.InlineComment.NotCapitalCodingStandard.Commenting.InlineComment.NotCapital
Errorcore/units/helpers/sections_helper.php:381PHPCS.E.CodingStandard.Classes.ClassDeclaration.SpaceBeforeCloseBraceCodingStandard.Classes.ClassDeclaration.SpaceBeforeCloseBrace
Errorcore/units/helpers/site_helper.php:87PHPCS.E.CodingStandard.WhiteSpace.ControlStructureSpacing.SpaceBeforeCloseBraceCodingStandard.WhiteSpace.ControlStructureSpacing.SpaceBeforeCloseBrace
Errorcore/units/helpers/site_helper.php:87PHPCS.E.CodingStandard.WhiteSpace.ControlStructureSpacing.SpacingAfterOpenBraceCodingStandard.WhiteSpace.ControlStructureSpacing.SpacingAfterOpenBrace
Unit
No Unit Test Coverage
Build Status
Buildable 1182
Build 1182: arc lint + arc unit

Event Timeline

alex created this revision.Feb 16 2023, 11:23 AM
alex requested review of this revision.Feb 16 2023, 11:23 AM
alex edited the test plan for this revision. (Show Details)Feb 16 2023, 11:30 AM
alex planned changes to this revision.Feb 16 2023, 11:33 AM
alex added a comment.EditedFeb 16 2023, 1:31 PM

TODO:

  1. write a test plan for:
    • memory cache testing
    • database cache testing
    • template cache testing (via cache_timeout tag parameter, m_Cache tag and similar stuff)
  2. store site serial with infinite expiration, because otherwise, it's expiration after 1 month will invalidate the whole cache
alex edited the test plan for this revision. (Show Details)Mar 16 2023, 10:34 AM
alex edited the test plan for this revision. (Show Details)Mar 16 2023, 11:58 AM
alex edited the test plan for this revision. (Show Details)Mar 16 2023, 12:20 PM
alex edited the test plan for this revision. (Show Details)Mar 16 2023, 12:26 PM
alex edited the test plan for this revision. (Show Details)Mar 16 2023, 12:28 PM
alex edited the test plan for this revision. (Show Details)Mar 17 2023, 4:58 AM
alex edited the test plan for this revision. (Show Details)Mar 17 2023, 6:15 AM
alex edited the test plan for this revision. (Show Details)Mar 17 2023, 6:43 AM
alex requested review of this revision.Mar 17 2023, 7:10 AM
alex edited the test plan for this revision. (Show Details)
alex updated this revision to Diff 1138.Mar 17 2023, 7:13 AM

Set infinite expiration for site serial key.

alex updated this revision to Diff 1139.Mar 17 2023, 11:04 AM

Fixed ArgumentCountError exception on the System Configuration step during clean install on PHP 7.4.

alex edited the test plan for this revision. (Show Details)Mar 17 2023, 11:06 AM
erik added a comment.Mar 17 2023, 1:55 PM

Detected that after memcache restart, test setCache with $application->setCache('key_with_def_exp', 'v1');, is passed only when twice open index.php. First index.php opening does not set value.

alex added a comment.Mar 20 2023, 3:41 AM
In D443#8964, @erik wrote:

Detected that after memcache restart, test setCache with $application->setCache('key_with_def_exp', 'v1');, is passed only when twice open index.php. First index.php opening does not set value.

I can confirm this behavior with the Memcache PHP extension. Seems like a PHP extension bug. I've updated the test plan.

Tested on the Memcached PHP extension (developed in D351) and no such issue there.

alex edited the test plan for this revision. (Show Details)Mar 20 2023, 3:47 AM
erik added a comment.Mar 20 2023, 6:10 AM

Testing internal caches expiration for Memcache
ITEM site_serial:1766886194:1:master:last_cache_rebuild [68 b; 0 s]
Failed condition "these keys have infinite expiration (the 1738250904 number might differ on your install)" - given "0 s" is not like some great integer like "1738250904"

alex edited the test plan for this revision. (Show Details)Mar 20 2023, 7:14 AM
In D443#8969, @erik wrote:

Testing internal caches expiration for Memcache
ITEM site_serial:1766886194:1:master:last_cache_rebuild [68 b; 0 s]
Failed condition "these keys have infinite expiration (the 1738250904 number might differ on your install)" - given "0 s" is not like some great integer like "1738250904"

Please also check other keys in the Testing internal caches expiration for Memcache test to see if they look as expected.

erik added a comment.Mar 20 2023, 7:54 AM

Testing internal caches expiration for Memcache
ITEM test [1 b; 0 s]
Failed condition "these keys have infinite expiration (the 1738250904 number might differ on your install)" - given "0 s" is not like some great integer like "1738250904"

some other keys, containing "master", found only with request

(sleep 1; echo "stats cachedump 3 0"; sleep 1; echo "quit";) | telnet localhost 11211 | grep 'master'
response:
ITEM site_serial:1766886194:1:master:cms_menu_serials [15 b; 0 s]
ITEM site_serial:1766886194:1:master:template_mapping_serials [23 b; 0 s]
ITEM site_serial:1766886194:1:master:last_cache_rebuild_serials [25 b; 0 s]
ITEM site_serial:1766886194:1:master:config_files_serials [19 b; 0 s]

keys have "_serials" at the end, so do not match keys from test plan
no other keys with "master" found with other requests

erik requested changes to this revision.Mar 20 2023, 9:38 AM
This revision now requires changes to proceed.Mar 20 2023, 9:38 AM
alex edited the test plan for this revision. (Show Details)Mar 21 2023, 11:53 AM
alex updated this revision to Diff 1142.Mar 21 2023, 11:56 AM

Replicated MemcacheCacheHandler class updates to the MemcachedCacheHandler class.

alex added a comment.Mar 21 2023, 12:02 PM
In D443#8977, @erik wrote:

Testing internal caches expiration for Memcache
ITEM test [1 b; 0 s]
Failed condition "these keys have infinite expiration (the 1738250904 number might differ on your install)" - given "0 s" is not like some great integer like "1738250904"

some other keys, containing "master", found only with request

(sleep 1; echo "stats cachedump 3 0"; sleep 1; echo "quit";) | telnet localhost 11211 | grep 'master'
response:
ITEM site_serial:1766886194:1:master:cms_menu_serials [15 b; 0 s]
ITEM site_serial:1766886194:1:master:template_mapping_serials [23 b; 0 s]
ITEM site_serial:1766886194:1:master:last_cache_rebuild_serials [25 b; 0 s]
ITEM site_serial:1766886194:1:master:config_files_serials [19 b; 0 s]

keys have "_serials" at the end, so do not match keys from test plan
no other keys with "master" found with other requests

  1. The 0 s effect was due to the Memcached server version difference between @alex (Memcached v. 1.4.15) and @erik (Memcached v. 1.6.15)
  2. The actual master: keys weren't missing, but were located in distant subs (18, 20, 21, 22, 23, and 25). This is likely the Memcached approach because these keys were very large.

Please retest and this time use key_memcache_dump.sh script, that scans all slabs for a given key, e.g. key_memcache_dump.sh master:.

erik added a comment.Mar 21 2023, 1:56 PM

Partially tested for Memcached. Failed test with $application->addCache('key_with_exp', 'v2', 3600);

Searched for new key with command key_memcache_dump.sh key_with

Script scanned 50 slab numbers and stopped. Found only this (lines with empty slabs omitted):

ITEM site_serial:1766886194:1:key_with_exp_serials [12 b; 1679428231 s]
ITEM site_serial:1766886194:1:key_with_def_exp [2 b; 1681584439 s]
Connection closed by foreign host.
Looking for 'key_with' key in 3 slab...
ITEM site_serial:1766886194:1:key_with_def_exp_serials [16 b; 1681584439 s]

erik added a comment.Mar 22 2023, 5:35 AM

Failed test "Testing internal caches expiration for DB cache" in the part "all other keys have an expiration of 25 days (with a few seconds margin) relative to the time they're set".

After test all other keys have 1h (3600s) lifetime{F470858}

erik requested changes to this revision.Mar 22 2023, 5:44 AM
This revision now requires changes to proceed.Mar 22 2023, 5:44 AM
alex added a comment.EditedMar 22 2023, 8:08 AM
In D443#8991, @erik wrote:

Partially tested for Memcached. Failed test with $application->addCache('key_with_exp', 'v2', 3600);

Searched for new key with command key_memcache_dump.sh key_with

Script scanned 50 slab numbers and stopped. Found only this (lines with empty slabs omitted):

ITEM site_serial:1766886194:1:key_with_exp_serials [12 b; 1679428231 s]
ITEM site_serial:1766886194:1:key_with_def_exp [2 b; 1681584439 s]
Connection closed by foreign host.
Looking for 'key_with' key in 3 slab...
ITEM site_serial:1766886194:1:key_with_def_exp_serials [16 b; 1681584439 s]

Can't get the same failure locally. I've used key_memcache_dump.sh key_with_exp command and key was found in the 2nd slab on both Memcache and Memcached caching handlers:

→ key_memcache_dump.sh key_with_exp
Looking for 'key_with_exp' key in 1 slab...
Connection closed by foreign host.
Looking for 'key_with_exp' key in 2 slab...
ITEM site_serial:1738250904:1:key_with_exp [2 b; 1679493833 s]
Connection closed by foreign host.
Looking for 'key_with_exp' key in 3 slab...
ITEM site_serial:1738250904:1:key_with_exp_serials [12 b; 1679493833 s]
Connection closed by foreign host.
Looking for 'key_with_exp' key in 4 slab...
Connection closed by foreign host.
In D443#8992, @erik wrote:

Failed test "Testing internal caches expiration for DB cache" in the part "all other keys have an expiration of 25 days (with a few seconds margin) relative to the time they're set".

After test all other keys have 1h (3600s) lifetime{F470858}

Confirmed. Fixed now.

alex edited the test plan for this revision. (Show Details)Mar 22 2023, 9:29 AM
alex updated this revision to Diff 1143.Mar 22 2023, 9:32 AM

Fixed issue, where database cache without expiration had 0 instead of -1 lifetime stored.

alex edited the test plan for this revision. (Show Details)Mar 22 2023, 9:46 AM
alex edited the test plan for this revision. (Show Details)Mar 22 2023, 9:49 AM

Updated test plan:

  • reformatted for easier reading
  • added cases for testing infinite expiration of developer-set keys
erik accepted this revision.Mar 22 2023, 12:22 PM
This revision is now accepted and ready to land.Mar 22 2023, 12:22 PM
alex added a project: Restricted Project.Mar 24 2023, 6:51 AM
This revision was landed with ongoing or failed builds.Nov 22 2023, 2:42 AM
This revision was automatically updated to reflect the committed changes.