Merge lp:~catch-drupal/pressflow/pressflow_implements into lp:pressflow

Proposed by Nathaniel Catchpole
Status: Superseded
Proposed branch: lp:~catch-drupal/pressflow/pressflow_implements
Merge into: lp:pressflow
Diff against target: 206 lines (+78/-27)
5 files modified
includes/common.inc (+2/-0)
includes/module.inc (+56/-5)
includes/path.inc (+1/-1)
install.php (+16/-20)
update.php (+3/-1)
To merge this branch: bzr merge lp:~catch-drupal/pressflow/pressflow_implements
Reviewer Review Type Date Requested Status
Pressflow Administrators Pending
Review via email: mp+40865@code.launchpad.net

This proposal has been superseded by a proposal from 2011-02-15.

Description of the change

Backport of Drupal 7 module_implements() caching. Adds one extra change to path.inc since the return value of $modules is now an associative array instead of numeric, otherwise identical to the core patch.

On a site with 150 modules instead, this reduced page execution time of module_implements() from around 4% of the request to less than 1%.

To post a comment you must log in.
98. By Nathaniel Catchpole <catch@catch-laptop>

 is now an associative array, so use reset instead of a hard-coded index.

99. By Nathaniel Catchpole <catch@catch-laptop>

Merge in trunk.

100. By Nathaniel <catch@catch-toshiba>

Merging in trunk.

Unmerged revisions

100. By Nathaniel <catch@catch-toshiba>

Merging in trunk.

99. By Nathaniel Catchpole <catch@catch-laptop>

Merge in trunk.

98. By Nathaniel Catchpole <catch@catch-laptop>

 is now an associative array, so use reset instead of a hard-coded index.

97. By Nathaniel Catchpole <catch@catch-laptop>

#557542: module_implements() caching.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'includes/common.inc'
--- includes/common.inc 2010-12-16 19:39:23 +0000
+++ includes/common.inc 2011-02-15 06:32:45 +0000
@@ -1620,6 +1620,8 @@
1620 if ($cache != CACHE_DISABLED && $cache != CACHE_EXTERNAL) {1620 if ($cache != CACHE_DISABLED && $cache != CACHE_EXTERNAL) {
1621 page_set_cache();1621 page_set_cache();
1622 }1622 }
1623 // Update the hook implementation cache.
1624 module_implements('', FALSE, FALSE, TRUE);
16231625
1624 module_invoke_all('exit');1626 module_invoke_all('exit');
1625}1627}
16261628
=== modified file 'includes/module.inc'
--- includes/module.inc 2010-12-16 19:28:18 +0000
+++ includes/module.inc 2011-02-15 06:32:45 +0000
@@ -406,27 +406,78 @@
406 * @param $sort406 * @param $sort
407 * By default, modules are ordered by weight and filename, settings this option407 * By default, modules are ordered by weight and filename, settings this option
408 * to TRUE, module list will be ordered by module name.408 * to TRUE, module list will be ordered by module name.
409 * @param $refresh409 * @param $reset
410 * For internal use only: Whether to force the stored list of hook410 * For internal use only: Whether to force the stored list of hook
411 * implementations to be regenerated (such as after enabling a new module,411 * implementations to be regenerated (such as after enabling a new module,
412 * before processing hook_enable).412 * before processing hook_enable).
413 * @param $write_cache
414 * For internal use only: Update the persistent cache of hook implementations.
413 * @return415 * @return
414 * An array with the names of the modules which are implementing this hook.416 * An array with the names of the modules which are implementing this hook.
415 */417 */
416function module_implements($hook, $sort = FALSE, $refresh = FALSE) {418function module_implements($hook, $sort = FALSE, $reset = FALSE, $write_cache = FALSE) {
417 static $implementations;419 static $implementations;
418420
419 if ($refresh) {421 // We maintain a persistent cache of hook implementations in addition to the
422 // static cache to avoid looping through every module and every hook on each
423 // request. Benchmarks show that the benefit of this caching outweighs the
424 // additional database hit even when using the default database caching
425 // backend and only a small number of modules are enabled. The cost of the
426 // cache_get() is more or less constant and reduced further when non-database
427 // caching backends are used, so there will be more significant gains when a
428 // large number of modules are installed or hooks invoked, since this can
429 // quickly lead to module_hook() being called several thousand times
430 // per request.
431 if ($reset) {
420 $implementations = array();432 $implementations = array();
421 return;433 cache_set('module_implements', array());
434 return;
435 }
436
437 if ($write_cache) {
438 // Check whether we should write the cache. We do not want to cache hooks
439 // which are only invoked on HTTP POST requests since these do not need to
440 // be optimized as tightly, and not doing so keeps the cache entry smaller.
441 if (isset($implementations['#write_cache']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD')) {
442 unset($implementations['#write_cache']);
443 cache_set('module_implements', $implementations);
444 }
445 return;
446 }
447
448 // Fetch implementations from cache.
449 if (empty($implementations)) {
450 $cache = cache_get('module_implements');
451 if (!$cache) {
452 $implementations = array();
453 }
454 else {
455 $implementations = $cache->data;
456 }
422 }457 }
423458
424 if (!isset($implementations[$hook])) {459 if (!isset($implementations[$hook])) {
460 // The hook is not cached, so ensure that whether or not it has
461 // implementations, that the cache is updated at the end of the request.
462 $implementations['#write_cache'] = TRUE;
425 $implementations[$hook] = array();463 $implementations[$hook] = array();
426 $list = module_list(FALSE, TRUE, $sort);464 $list = module_list(FALSE, TRUE, $sort);
427 foreach ($list as $module) {465 foreach ($list as $module) {
428 if (module_hook($module, $hook)) {466 if (module_hook($module, $hook)) {
429 $implementations[$hook][] = $module;467 $implementations[$hook][$module] = $module;
468 }
469 }
470 }
471 else {
472 foreach ($implementations[$hook] as $module) {
473 // It is possible that a module removed a hook implementation without the
474 // implementations cache being rebuilt yet, so we check module_hook() on
475 // each request to avoid undefined function errors.
476 if (!module_hook($module, $hook)) {
477 // Clear out the stale implementation from the cache and force a cache
478 // refresh to forget about no longer existing hook implementations.
479 unset($implementations[$hook][$module]);
480 $implementations['#write_cache'] = TRUE;
430 }481 }
431 }482 }
432 }483 }
433484
=== modified file 'includes/path.inc'
--- includes/path.inc 2010-12-16 19:39:23 +0000
+++ includes/path.inc 2011-02-15 06:32:45 +0000
@@ -51,7 +51,7 @@
51 if (!isset($hook_module)) {51 if (!isset($hook_module)) {
52 $modules = module_implements('lookup_path');52 $modules = module_implements('lookup_path');
53 if (count($modules) > 0) {53 if (count($modules) > 0) {
54 $hook_module = $modules[0];54 $hook_module = reset($modules);
55 } else {55 } else {
56 $hook_module = FALSE;56 $hook_module = FALSE;
57 }57 }
5858
=== modified file 'install.php'
--- install.php 2010-12-16 19:39:23 +0000
+++ install.php 2011-02-15 06:32:45 +0000
@@ -48,6 +48,18 @@
48 drupal_load('module', 'system');48 drupal_load('module', 'system');
49 drupal_load('module', 'filter');49 drupal_load('module', 'filter');
5050
51 // Load the cache infrastructure using a "fake" cache implementation that
52 // does not attempt to write to the database. We need this during the initial
53 // part of the installer because the database is not available yet. We
54 // continue to use it even when the database does become available, in order
55 // to preserve consistency between interactive and command-line installations
56 // (the latter complete in one page request and therefore are forced to
57 // continue using the cache implementation they started with) and also
58 // because any data put in the cache during the installer is inherently
59 // suspect, due to the fact that Drupal is not fully set up yet.
60 require_once './includes/cache-install.inc';
61 $conf['cache_inc'] = './includes/cache-install.inc';
62
51 // Install profile chosen, set the global immediately.63 // Install profile chosen, set the global immediately.
52 // This needs to be done before the theme cache gets 64 // This needs to be done before the theme cache gets
53 // initialized in drupal_maintenance_theme().65 // initialized in drupal_maintenance_theme().
@@ -62,12 +74,6 @@
62 $verify = install_verify_settings();74 $verify = install_verify_settings();
6375
64 if ($verify) {76 if ($verify) {
65 // Since we have a database connection, we use the normal cache system.
66 // This is important, as the installer calls into the Drupal system for
67 // the clean URL checks, so we should maintain the cache properly.
68 require_once './includes/cache.inc';
69 $conf['cache_inc'] = './includes/cache.inc';
70
71 // Establish a connection to the database.77 // Establish a connection to the database.
72 require_once './includes/database.inc';78 require_once './includes/database.inc';
73 db_set_active();79 db_set_active();
@@ -79,13 +85,6 @@
79 }85 }
80 }86 }
81 else {87 else {
82 // Since no persistent storage is available yet, and functions that check
83 // for cached data will fail, we temporarily replace the normal cache
84 // system with a stubbed-out version that short-circuits the actual
85 // caching process and avoids any errors.
86 require_once './includes/cache-install.inc';
87 $conf['cache_inc'] = './includes/cache-install.inc';
88
89 $task = NULL;88 $task = NULL;
90 }89 }
9190
@@ -816,17 +815,14 @@
816815
817 // The end of the install process. Remember profile used.816 // The end of the install process. Remember profile used.
818 if ($task == 'done') {817 if ($task == 'done') {
819 // Rebuild menu to get content type links registered by the profile,818 // Flush all caches to ensure that any full bootstraps during the installer
820 // and possibly any other menu items created through the tasks.819 // do not leave stale cached data, and that any content types or other items
821 menu_rebuild();820 // registered by the install profile are registered correctly.
821 drupal_flush_all_caches();
822822
823 // Register actions declared by any modules.823 // Register actions declared by any modules.
824 actions_synchronize();824 actions_synchronize();
825825
826 // Randomize query-strings on css/js files, to hide the fact that
827 // this is a new install, not upgraded yet.
828 _drupal_flush_css_js();
829
830 variable_set('install_profile', $profile);826 variable_set('install_profile', $profile);
831 }827 }
832828
833829
=== modified file 'update.php'
--- update.php 2010-12-16 19:39:23 +0000
+++ update.php 2011-02-15 06:32:45 +0000
@@ -595,7 +595,7 @@
595$op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';595$op = isset($_REQUEST['op']) ? $_REQUEST['op'] : '';
596if (empty($op)) {596if (empty($op)) {
597 // Minimum load of components.597 // Minimum load of components.
598 drupal_bootstrap(DRUPAL_BOOTSTRAP_CONFIGURATION);598 drupal_bootstrap(DRUPAL_BOOTSTRAP_DATABASE);
599599
600 require_once './includes/install.inc';600 require_once './includes/install.inc';
601 require_once './includes/file.inc';601 require_once './includes/file.inc';
@@ -606,6 +606,8 @@
606 $module_list['system']['filename'] = 'modules/system/system.module';606 $module_list['system']['filename'] = 'modules/system/system.module';
607 $module_list['filter']['filename'] = 'modules/filter/filter.module';607 $module_list['filter']['filename'] = 'modules/filter/filter.module';
608 module_list(TRUE, FALSE, FALSE, $module_list);608 module_list(TRUE, FALSE, FALSE, $module_list);
609 module_implements('', FALSE, TRUE);
610
609 drupal_load('module', 'system');611 drupal_load('module', 'system');
610 drupal_load('module', 'filter');612 drupal_load('module', 'filter');
611613

Subscribers

People subscribed via source and target branches

to status/vote changes: