-
Bug
-
Resolution: Fixed
-
Minor
-
4.1.11
We've found a race condition when using alternative_cache_factory_class on the first read or write of a cache after a purge due to a chicken and egg related to siteidentifier. Honestly pretty surprising we haven't found it for so long. It's very hard and likely impossible to unit test because you are testing the bootstrap itself.
When moodle bootstraps, it loads:
- the dml library
- then cache library
- open the db connection
- reads localcache/bootstrap.php if it exists which stores the siteidentifier, file doesn't exist after a cache purge
- runs initialise_cfg to load config including the $CFG->siteidentifier from the database
- the DML layer uses MUC to cache metadata (in postgres but not mysql)
- MUC needs the siteid in order to configure the cache
So we have a chicken and egg situation, steps 5-7 needs the site id for the db to work which needs the cache which needs the db. The default implementation in core works around this by using an interim value of 'unknown' for the site id:
https://github.com/moodle/moodle/blob/master/cache/classes/config.php#L147
This doesn't actually change anything though and it temporarily uses that siteid and then replaces it later with the real one.
However when you override the alternative_cache_factory_class we don't seem to have a convenient way to do the same thing (might be wrong on this).
So proposing two solutions:
a) when we bootstrap, if we don't have the siteid yet (step 4) then we simply disable the cache factory so the first request warms the bootstrap.php file
b) maybe there is a better solution which means we can warm in a single request which would be disabling muc temporarily just until that first DB call to mdl_config happens