Index: branches/5.2.x/core/kernel/managers/cache_manager.php =================================================================== diff -u -N -r14447 -r14560 --- branches/5.2.x/core/kernel/managers/cache_manager.php (.../cache_manager.php) (revision 14447) +++ branches/5.2.x/core/kernel/managers/cache_manager.php (.../cache_manager.php) (revision 14560) @@ -1,6 +1,6 @@ Application->isCachingType(CACHING_TYPE_MEMORY)) { - $data = $this->Application->getCache('master:configs_parsed', false); + if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { + $data = $this->Application->getCache('master:configs_parsed', false, CacheSettings::$unitCacheRebuildTime); } else { - $data = $this->Application->getDBCache('configs_parsed'); + $data = $this->Application->getDBCache('configs_parsed', CacheSettings::$unitCacheRebuildTime); } - if ($data) { + if ( $data ) { $cache = unserialize($data); // 126 KB all modules unset($data); @@ -230,6 +230,13 @@ } + if ( $this->Application->isCachingType(CACHING_TYPE_MEMORY) ) { + $this->Application->rebuildCache('master:configs_parsed', kCache::REBUILD_NOW, CacheSettings::$unitCacheRebuildTime); + } + else { + $this->Application->rebuildDBCache('configs_parsed', kCache::REBUILD_NOW, CacheSettings::$unitCacheRebuildTime); + } + return false; } @@ -326,18 +333,18 @@ public function DeleteUnitCache($include_sections = false) { if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) { - $this->Application->deleteCache('master:configs_parsed'); + $this->Application->rebuildCache('master:configs_parsed', kCache::REBUILD_LATER, CacheSettings::$unitCacheRebuildTime); } else { - $this->Application->deleteDBCache('configs_parsed'); + $this->Application->rebuildDBCache('configs_parsed', kCache::REBUILD_LATER, CacheSettings::$unitCacheRebuildTime); } if ($include_sections) { if ($this->Application->isCachingType(CACHING_TYPE_MEMORY)) { - $this->Application->deleteCache('master:sections_parsed'); + $this->Application->rebuildCache('master:sections_parsed', kCache::REBUILD_LATER, CacheSettings::$sectionsParsedRebuildTime); } else { - $this->Application->deleteDBCache('sections_parsed'); + $this->Application->rebuildDBCache('sections_parsed', kCache::REBUILD_LATER, CacheSettings::$sectionsParsedRebuildTime); } } } @@ -447,12 +454,13 @@ * * @param int $key key name from cache * @param bool $store_locally store data locally after retrieved + * @param int $max_rebuild_seconds * @return mixed * @access public */ - public function getCache($key, $store_locally = true) + public function getCache($key, $store_locally = true, $max_rebuild_seconds = 0) { - return $this->cacheHandler->getCache($key, $store_locally); + return $this->cacheHandler->getCache($key, $store_locally, $max_rebuild_seconds); } /** @@ -469,6 +477,18 @@ } /** + * Sets rebuilding mode for given cache + * + * @param string $name + * @param int $mode + * @param int $max_rebuilding_time + */ + public function rebuildCache($name, $mode = null, $max_rebuilding_time = 0) + { + $this->cacheHandler->rebuildCache($name, $mode, $max_rebuilding_time); + } + + /** * Deletes key from cache * * @param string $key @@ -493,11 +513,51 @@ * Returns value from database cache * * @param string $name key name + * @param int $max_rebuild_seconds * @return mixed * @access public */ - public function getDBCache($name) + public function getDBCache($name, $max_rebuild_seconds = 0) { + if ( $this->_getDBCache($name . '_rebuild') ) { + // cache rebuild requested -> rebuild now + $this->deleteDBCache($name . '_rebuild'); + + return false; + } + + // no serials in cache key OR cache is outdated + $wait_seconds = $max_rebuild_seconds; + + while (true) { + $cache = $this->_getDBCache($name); + $rebuilding = $this->_getDBCache($name . '_rebuilding'); + + if ( ($cache === false) && (!$rebuilding || $wait_seconds == 0) ) { + // cache missing and nobody rebuilding it -> rebuild; enough waiting for cache to be ready + return false; + } + elseif ( $cache !== false ) { + // cache present -> return it + return $cache; + } + + $wait_seconds -= kCache::WAIT_STEP; + sleep(kCache::WAIT_STEP); + } + + return false; + } + + /** + * Returns value from database cache + * + * @param string $name key name + * @return mixed + * @access protected + */ + protected function _getDBCache($name) + { $this->Conn->nextQueryCachable = true; $sql = 'SELECT Data, Cached, LifeTime @@ -529,11 +589,25 @@ * * @param string $name * @param mixed $value - * @param int $expiration + * @param int|bool $expiration * @access public */ public function setDBCache($name, $value, $expiration = false) { + $this->deleteDBCache($name . '_rebuilding'); + $this->_setDBCache($name, $value, $expiration); + } + + /** + * Sets value to database cache + * + * @param string $name + * @param mixed $value + * @param int|bool $expiration + * @access protected + */ + protected function _setDBCache($name, $value, $expiration = false) + { if ((int)$expiration <= 0) { $expiration = -1; } @@ -550,6 +624,25 @@ } /** + * Sets rebuilding mode for given cache + * + * @param string $name + * @param int $mode + * @param int $max_rebuilding_time + */ + public function rebuildDBCache($name, $mode = null, $max_rebuilding_time = 0) + { + if ( !isset($mode) || $mode == kCache::REBUILD_NOW ) { + $this->_setDBCache($name . '_rebuilding', 1, $max_rebuilding_time); + $this->deleteDBCache($name . '_rebuild'); + } + elseif ( $mode == kCache::REBUILD_LATER ) { + $this->_setDBCache($name . '_rebuild', 1, 0); + $this->deleteDBCache($name . '_rebuilding'); + } + } + + /** * Deletes key from database cache * * @param string $name