diff options
-rw-r--r-- | modules/update/update.compare.inc | 61 | ||||
-rw-r--r-- | modules/update/update.fetch.inc | 7 | ||||
-rw-r--r-- | modules/update/update.module | 2 |
3 files changed, 67 insertions, 3 deletions
diff --git a/modules/update/update.compare.inc b/modules/update/update.compare.inc index 30ae642fd..5c7c914f9 100644 --- a/modules/update/update.compare.inc +++ b/modules/update/update.compare.inc @@ -23,8 +23,15 @@ function update_get_projects() { static $projects = array(); if (empty($projects)) { - _update_process_info_list($projects, module_rebuild_cache(), 'module'); - _update_process_info_list($projects, system_theme_data(), 'theme'); + // Retrieve the projects from cache, if present. + $projects = update_project_cache('update_project_projects'); + if (empty($projects)) { + // Still empty, so we have to rebuild the cache. + _update_process_info_list($projects, module_rebuild_cache(), 'module'); + _update_process_info_list($projects, system_theme_data(), 'theme'); + // Set the projects array into the cache table. + cache_set('update_project_projects', $projects, 'cache_update', time() + 3600); + } } return $projects; } @@ -225,6 +232,13 @@ function update_process_project_info(&$projects) { * @see update_process_project_info() */ function update_calculate_project_data($available) { + // Retrieve the projects from cache, if present. + $projects = update_project_cache('update_project_data'); + // If $projects is empty, then the cache must be rebuilt. + // Otherwise, return the cached data and skip the rest of the function. + if (!empty($projects)) { + return $projects; + } $projects = update_get_projects(); update_process_project_info($projects); foreach ($projects as $project => $project_info) { @@ -535,5 +549,48 @@ function update_calculate_project_data($available) { // contrib module to provide fine-grained settings to ignore specific // projects or releases). drupal_alter('update_status', $projects); + + // Set the projects array into the cache table. + cache_set('update_project_data', $projects, 'cache_update', time() + 3600); + return $projects; +} + +/** + * Retrieve data from {cache_update} or empty the cache when necessary. + * + * Two very expensive arrays computed by this module are the list of all + * installed modules and themes (and .info data, project associations, etc), + * and the current status of the site relative to the currently available + * releases. These two arrays are cached in the {cache_update} table and used + * whenever possible. The cache is cleared whenever the administrator visits + * the status report, available updates report, or the module or theme + * administration pages, since we should always recompute the most current + * values on any of those pages. + * + * @param $cid + * The cache id of data to return from the cache. Valid options are + * 'update_project_data' and 'update_project_projects'. + * + * @return + * The cached value of the $projects array generated by + * update_calculate_project_data() or update_get_projects(), or an empty + * array when the cache is cleared. + */ +function update_project_cache($cid) { + $projects = array(); + + // In some cases, we must clear the cache. Rather than do so on a time + // basis, we check for specific paths. + $q = $_GET['q']; + $paths = array('admin/build/modules', 'admin/build/themes', 'admin/reports', 'admin/reports/updates', 'admin/reports/status', 'admin/reports/updates/check'); + if (in_array($q, $paths)) { + cache_clear_all($cid, 'cache_update'); + } + else { + $cache = cache_get($cid, 'cache_update'); + if (!empty($cache->data) && $cache->expire > time()) { + $projects = $cache->data; + } + } return $projects; } diff --git a/modules/update/update.fetch.inc b/modules/update/update.fetch.inc index 4ecdbc235..ce4c836a8 100644 --- a/modules/update/update.fetch.inc +++ b/modules/update/update.fetch.inc @@ -26,6 +26,13 @@ function _update_refresh() { global $base_url; include_once './modules/update/update.compare.inc'; + // Since we're fetching new available update data, we want to clear + // everything in our cache, to ensure we recompute the status. Note that + // this does not cause update_get_projects() to be recomputed twice in the + // same page load (e.g. when manually checking) since that function stashes + // its answer in a static array. + update_invalidate_cache(); + $available = array(); $data = array(); $site_key = md5($base_url . drupal_get_private_key()); diff --git a/modules/update/update.module b/modules/update/update.module index 8f624c5c9..204047e8c 100644 --- a/modules/update/update.module +++ b/modules/update/update.module @@ -379,7 +379,7 @@ function update_flush_caches() { * Invalidates any cached data relating to update status. */ function update_invalidate_cache() { - cache_clear_all('update_info', 'cache_update'); + cache_clear_all('*', 'cache_update', TRUE); } /** |