? block_cache_8.patch
? block_cache_9.patch
Index: modules/block/block.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.module,v
retrieving revision 1.274
diff -u -F^f -r1.274 block.module
--- modules/block/block.module 24 Jul 2007 18:17:30 -0000 1.274
+++ modules/block/block.module 9 Aug 2007 16:42:49 -0000
@@ -13,6 +13,19 @@
define('BLOCK_REGION_NONE', -1);
/**
+ * Flags defining cache granularity for cached blocks.
+ *
+ * BLOCK_CACHE_CUSTOM lets modules define their own critrions
+ * using hook_block('cache_id').
+ */
+define('BLOCK_NO_CACHE', -1);
+define('BLOCK_CACHE_GLOBAL', 0x0001);
+define('BLOCK_CACHE_PER_PAGE', 0x0002);
+define('BLOCK_CACHE_PER_USER', 0x0004);
+define('BLOCK_CACHE_PER_ROLE', 0x0008);
+define('BLOCK_CACHE_CUSTOM', 0x0010);
+
+/**
* Implementation of hook_help().
*/
function block_help($path, $arg) {
@@ -235,6 +248,7 @@ function _block_rehash() {
foreach ($module_blocks as $delta => $block) {
$block['module'] = $module;
$block['delta'] = $delta;
+ $block['cache'] = isset($block['cache']) ? $block['cache'] : BLOCK_CACHE_PER_ROLE;
// If previously written to database, load values.
if (!empty($old_blocks[$module][$delta])) {
$block['status'] = $old_blocks[$module][$delta]->status;
@@ -271,7 +285,7 @@ function _block_rehash() {
'visibility' => NULL,
'throttle' => NULL,
);
- db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s')", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title']);
+ db_query("INSERT INTO {blocks} (module, delta, theme, status, weight, region, visibility, pages, custom, throttle, title, cache) VALUES ('%s', '%s', '%s', %d, %d, '%s', %d, '%s', %d, %d, '%s', %d)", $block['module'], $block['delta'], $theme_key, $block['status'], $block['weight'], $block['region'], $block['visibility'], $block['pages'], $block['custom'], $block['throttle'], $block['title'], $block['cache']);
}
db_unlock_tables();
@@ -429,7 +443,19 @@ function block_list($region) {
// Check the current throttle status and see if block should be displayed
// based on server load.
if (!($block->throttle && (module_invoke('throttle', 'status') > 0))) {
- $array = module_invoke($block->module, 'block', 'view', $block->delta);
+ // Try fetching the block from cache. Block caching is not compatible with
+ // node_access modules. We also preserve the submission of forms in blocks,
+ // by fetching from cache only if the request is 'GET'.
+ if (!count(module_implements('node_grants')) && $_SERVER['REQUEST_METHOD'] == 'GET' && ($cid = _block_get_cache_id($block)) && ($cache = cache_get($cid, 'cache_block'))) {
+ $array = $cache->data;
+ }
+ else {
+ $array = module_invoke($block->module, 'block', 'view', $block->delta);
+ if (isset($cid)) {
+ cache_set($cid, $array, 'cache_block', variable_get('cache_lifetime', CACHE_TEMPORARY));
+ }
+ }
+
if (isset($array) && is_array($array)) {
foreach ($array as $k => $v) {
$block->$k = $v;
@@ -453,3 +479,57 @@ function block_list($region) {
}
return $blocks[$region];
}
+
+/**
+ * Determine the block caching granularity.
+ *
+ * @param $block
+ * @return
+ * The string used as cid for the block
+ */
+function _block_get_cache_id($block) {
+ global $theme, $base_root, $user;
+
+ // User 1 being out of the regular 'roles define permissions' schema,
+ // it brings too many chances of having unwanted output get in the cache
+ // and later be served to other users.
+ if (variable_get('block_cache', 0) && $block->cache != BLOCK_NO_CACHE && $user->uid != 1) {
+
+ $base_cid = "$block->module:$block->delta:$theme";
+ if (module_exists('locale')) {
+ global $language;
+ $base_cid .= ":$language->language";
+ }
+
+ $cid_parts = array();
+
+ // Let the module define specific cache granularity.
+ if ($block->cache & BLOCK_CACHE_CUSTOM) {
+ $cid_parts[] = module_invoke($block->module, 'block', 'cache_id', $block->delta);
+ }
+
+ // 'per role' and 'per user' are mutually exclusive :
+ // we favor the less expensive 'per role'.
+ if ($block->cache & BLOCK_CACHE_PER_ROLE) {
+ $cid_parts[] = 'r_'. implode(',', array_keys($user->roles));
+ }
+ elseif ($block->cache & BLOCK_CACHE_PER_USER) {
+ $cid_parts[] = "u_$user->uid";
+ }
+
+ if ($block->cache & BLOCK_CACHE_PER_PAGE) {
+ $cid_parts[] = $base_root . request_uri();
+ }
+
+ return "$base_cid:". implode(':', $cid_parts);
+ }
+}
+
+/**
+ * Implementation of hook_cron().
+ *
+ * Expire outdated block cache entries
+ */
+function block_cron() {
+ cache_clear_all(NULL, 'cache_block');
+}
Index: modules/block/block.schema
===================================================================
RCS file: /cvs/drupal/drupal/modules/block/block.schema,v
retrieving revision 1.1
diff -u -F^f -r1.1 block.schema
--- modules/block/block.schema 25 May 2007 12:46:43 -0000 1.1
+++ modules/block/block.schema 9 Aug 2007 16:42:49 -0000
@@ -15,7 +15,8 @@ function block_schema() {
'throttle' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'),
'visibility' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'),
'pages' => array('type' => 'text', 'not null' => TRUE),
- 'title' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => '')
+ 'title' => array('type' => 'varchar', 'length' => 64, 'not null' => TRUE, 'default' => ''),
+ 'cache' => array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'),
),
'primary key' => array('bid'),
);
@@ -44,6 +45,8 @@ function block_schema() {
'primary key' => array('bid'),
);
+ $schema['cache_block'] = drupal_get_schema_unprocessed('system', 'cache');
+
return $schema;
}
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.570
diff -u -F^f -r1.570 comment.module
--- modules/comment/comment.module 30 Jul 2007 21:27:34 -0000 1.570
+++ modules/comment/comment.module 9 Aug 2007 16:42:49 -0000
@@ -270,6 +270,7 @@ function comment_perm() {
function comment_block($op = 'list', $delta = 0) {
if ($op == 'list') {
$blocks[0]['info'] = t('Recent comments');
+ $blocks[1]['cache_mode'] = BLOCK_CACHE_PER_ROLE;
return $blocks;
}
else if ($op == 'view' && user_access('access comments')) {
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.412
diff -u -F^f -r1.412 forum.module
--- modules/forum/forum.module 3 Aug 2007 06:07:52 -0000 1.412
+++ modules/forum/forum.module 9 Aug 2007 16:42:50 -0000
@@ -357,7 +357,9 @@ function forum_block($op = 'list', $delt
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Active forum topics');
+ $blocks[0]['cache_mode'] = BLOCK_CACHE_PER_PAGE & BLOCK_CACHE_PER_USER;
$blocks[1]['info'] = t('New forum topics');
+ $blocks[1]['cache_mode'] = BLOCK_CACHE_PER_PAGE & BLOCK_CACHE_PER_USER;
return $blocks;
case 'configure':
Index: modules/menu/menu.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/menu/menu.module,v
retrieving revision 1.132
diff -u -F^f -r1.132 menu.module
--- modules/menu/menu.module 29 Jul 2007 17:28:23 -0000 1.132
+++ modules/menu/menu.module 9 Aug 2007 16:42:50 -0000
@@ -635,6 +635,8 @@ function menu_block($op = 'list', $delta
foreach ($custom_menus as $name => $title) {
// Default "Navigation" block is handled by user.module.
$blocks[$name]['info'] = check_plain($title);
+ // Menu blocks might be different even for the same path.
+ $blocks[$name]['cache'] = BLOCK_NO_CACHE;
}
return $blocks;
}
Index: modules/node/node.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/node/node.module,v
retrieving revision 1.866
diff -u -F^f -r1.866 node.module
--- modules/node/node.module 9 Aug 2007 11:00:59 -0000 1.866
+++ modules/node/node.module 9 Aug 2007 16:42:50 -0000
@@ -1896,6 +1896,7 @@ function node_admin_search() {
function node_block($op = 'list', $delta = 0) {
if ($op == 'list') {
$blocks[0]['info'] = t('Syndicate');
+ $blocks[0]['cache'] = BLOCK_CACHE_GLOBAL;
return $blocks;
}
else if ($op == 'view') {
Index: modules/system/system.install
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.install,v
retrieving revision 1.132
diff -u -F^f -r1.132 system.install
--- modules/system/system.install 7 Aug 2007 08:32:43 -0000 1.132
+++ modules/system/system.install 9 Aug 2007 16:42:51 -0000
@@ -3476,6 +3476,28 @@ function system_update_6026() {
}
/**
+ * Add cache_block table.
+ */
+function system_update_6027() {
+ $ret = array();
+ db_add_field($ret, 'blocks', 'cache', array('type' => 'int', 'not null' => TRUE, 'default' => 0, 'size' => 'tiny'));
+ $schema['cache_block'] = array(
+ 'fields' => array(
+ 'cid' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''),
+ 'data' => array('type' => 'blob', 'not null' => FALSE, 'size' => 'big'),
+ 'expire' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0),
+ 'headers' => array('type' => 'text', 'not null' => FALSE),
+ 'serialized' => array('type' => 'int', 'size' => 'small', 'not null' => TRUE, 'default' => 0)
+ ),
+ 'indexes' => array('expire' => array('expire')),
+ 'primary key' => array('cid'),
+ );
+ db_create_table($ret, $schema['cache_block']);
+ return $ret;
+}
+
+/**
* @} End of "defgroup updates-5.x-to-6.x"
* The next series of updates should start at 7000.
*/
Index: modules/system/system.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/system/system.module,v
retrieving revision 1.513
diff -u -F^f -r1.513 system.module
--- modules/system/system.module 2 Aug 2007 20:19:02 -0000 1.513
+++ modules/system/system.module 9 Aug 2007 16:42:51 -0000
@@ -682,7 +682,7 @@ function system_performance_settings() {
$form['page_cache'] = array(
'#type' => 'fieldset',
'#title' => t('Page cache'),
- '#description' => t('Enabling the cache will offer a significant performance boost. Drupal can store and send compressed cached pages requested by anonymous users. By caching a web page, Drupal does not have to construct the page each time someone wants to view it.'),
+ '#description' => t('Enabling the page cache will offer a significant performance boost. Drupal can store and send compressed cached pages requested by anonymous users. By caching a web page, Drupal does not have to construct the page each time someone wants to view it.'),
);
$form['page_cache']['cache'] = array(
@@ -703,6 +703,21 @@ function system_performance_settings() {
'#description' => t('On high-traffic sites it can become necessary to enforce a minimum cache lifetime. The minimum cache lifetime is the minimum amount of time that will go by before the cache is emptied and recreated. A larger minimum cache lifetime offers better performance, but users will not see new content for a longer period of time.')
);
+ $form['block_cache'] = array(
+ '#type' => 'fieldset',
+ '#title' => t('Block cache'),
+ '#description' => t('Enabling the block cache will enhance performance for pages requested by any user (anonymous or authenticated). It can be enabled or disabled indenpendently of the page cache.'),
+ );
+
+ $form['block_cache']['block_cache'] = array(
+ '#type' => 'radios',
+ '#title' => t('Block cache'),
+ '#default_value' => variable_get('block_cache', CACHE_DISABLED),
+ '#options' => array(CACHE_DISABLED => t('Disabled'), CACHE_NORMAL => t('Enabled (recommended)')),
+ '#disabled' => count(module_implements('node_grants')),
+ '#description' => t('Note that block caching is inactive when modules defining content access restrictions are enabled.'),
+ );
+
$form['bandwidth_optimizations'] = array(
'#type' => 'fieldset',
'#title' => t('Bandwidth optimizations'),
Index: modules/user/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user/user.module,v
retrieving revision 1.827
diff -u -F^f -r1.827 user.module
--- modules/user/user.module 9 Aug 2007 10:49:26 -0000 1.827
+++ modules/user/user.module 9 Aug 2007 16:42:52 -0000
@@ -628,10 +628,14 @@ function user_block($op = 'list', $delta
if ($op == 'list') {
$blocks[0]['info'] = t('User login');
+ // Contains a redirect url which changes with each page view.
+ $blocks[0]['cache'] = BLOCK_CACHE_PER_PAGE;
$blocks[1]['info'] = t('Navigation');
+ $blocks[1]['cache'] = BLOCK_CACHE_PER_PAGE & BLOCK_CACHE_PER_USER;
$blocks[2]['info'] = t('Who\'s new');
+ // Too dynamic to cache
$blocks[3]['info'] = t('Who\'s online');
-
+ $blocks[3]['cache'] = BLOCK_NO_CACHE;
return $blocks;
}
else if ($op == 'configure' && $delta == 2) {