Block cache should be BLOCK_NO_CACHE

andypost - February 8, 2009 - 05:45
Project:Privatemsg
Version:6.x-1.x-dev
Component:Code
Category:bug report
Priority:critical
Assigned:Unassigned
Status:closed
Description

there's no refresh if user recive message because "cache" is not set in hook_block

This should be by default but how to change it for current users.

Maybe new hook_update_N in .install

AttachmentSize
pm_block_d6.patch596 bytes

#1

andypost - February 8, 2009 - 06:07
Priority:normal» critical

Version with patch bot .module and .install files

This is critical to UI bacause ALL users see same block with COUNT from user who open the page first...

AttachmentSize
pm_block2_d6.patch 1.27 KB

#3

andypost - February 8, 2009 - 07:39

@litwol 6.x-1.0-rc2 still defines block without BLOCK_CACHE_PER_USER so update_6002 is needed.

CVS DRUPAL-6--1 already holds BLOCK_CACHE_PER_USER definition for block but there's not update function in .install

This patch should wait till #370960: Remove t() from all schema descriptions

#4

Berdir - February 8, 2009 - 12:18

Do we really need to update the cache table ? That should be done automatically when update.php is called, which does clear the cache, not?

#5

andypost - February 8, 2009 - 14:50

@Berdir update block table - not cache

#6

Berdir - February 8, 2009 - 16:13
Status:needs review» needs work

But then your patch is wrong :)

.. + $ret[] = update_sql("UPDATE {cache} SET cache = 2 WHERE module='privatemsg' AND delta='privatemsg-menu'"); ...

#7

andypost - February 8, 2009 - 18:55
Status:needs work» needs review

Sorry, blocks not cache
patch against -6--1

AttachmentSize
pm_sd6.patch 1.4 KB

#8

litwol - February 8, 2009 - 20:22
Status:needs review» needs work

Instead of 'cache = 2' you need to use combination of 'cache = %d' and BLOCK_CACHE_PER_USER as query argument.

#9

andypost - February 9, 2009 - 14:47

@litwol Agree exactly

AttachmentSize
pm_s2d6.patch 1.52 KB

#10

andypost - February 10, 2009 - 15:19

There are some ideas - previous way is wrong

1) Quick solution - set block->cache to BLOCK_NO_CACHE and check for new messages on every page request
2) Advanced - leave BLOCK_CACHE_PER_USER but make some logic for sending messages
- clear cache per recipient when message is sent
- clear own cache when user oen a message

Suppose 2 is little hard to implement but it brings some perfomance (I'll try)

But wanna know opinion of maintainers

#11

Berdir - February 10, 2009 - 15:58

3) Convert the block to a menu, so that everything except the number of new messages is cached, which is loaded anyway. Devel does this now too, see 'menu_name' option at http://api.drupal.org/api/function/hook_menu/6

#12

litwol - February 10, 2009 - 16:07

the idea behind caching is to avoid executing long queries (those that scan whole pmsg tables). (2) aligns well with what i was brainstorming about last night in IRC with Berdir. we should flush cache per user when they receive messages.

#13

andypost - February 10, 2009 - 16:45

At this moment I see 2 blocks + menuitem they all brings same functionality (notify users about new messages)

All of them call only one function privatemsg_unread_count() which executes query only once and staticaly caches the result so no matter how offen it called.

Menu item updates on *privatemsg_title_callback*

This 2 blocks never updates (I found no cache_clear_all) they should called on send for all recipients

<?php
$block
= new stdClass();
$block->module = 'privatemsg';
$block->delta = 'privatemsg-menu'; //privatemsg-new
$block->cache = BLOCK_CACHE_PER_USER;

//Calculate hash for block but only for current user
$cid = _block_get_cache_id($block);
cache_clear_all($cid, 'cache_block');
?>

I use this code in some parts but when I need clear cache for different users I need to know there $theme $language
So I change the _block_get_cache_id by my own function

<?php
function _mymodule_clear_cache($uid) {
  if (
variable_get('block_cache', 0)) {
    global
$theme;
   
$save = $theme;
   
$themes = list_themes();
    foreach (
$themes as $tmp) {
     
$theme = $tmp->name;
     
$block = new stdClass();
     
$block->module = 'click2bookmark';
     
$block->delta = 0;
     
$block->cache = BLOCK_CACHE_PER_USER;
      if (
$cid = _block_get_cache_id($block)) {
       
cache_clear_all($cid, 'cache_block');
      }
    }
   
$theme = $save;
  }
}
?>

This function work only for current user but clears cache for all user's themes (all themes)
It's easy to change (copy/paste) *_block_get_cache_id* code to make cache_id depending on needs

#14

Berdir - March 5, 2009 - 14:23
Status:needs work» needs review

I tried to get this working, but pretty much failed. It is just too complex. The main issue is that we don't only need to clear the cache for the current user but for all recipients, too. And these users could have another language and theme. And there are multiple blocks, at the moment two, both could be actived.. or not.

Additionaly, I'm not even sure if we gain anything by using the cache at all. Both blocks just display some text with a single query, that is only executed once and, because of the menu callback, executed anyway. So, all needed resources are either already cached (translation), use static cache (unread count, permissions) or are just simple strings. If using a cache, it would execute a query per block unless a cache backend like apc or memcached is used.

My suggestion:
use BLOCK_NO_CACHE for both blocks, patch is attached.

AttachmentSize
privatemsg.block_cache.patch 1.6 KB

#15

andypost - March 5, 2009 - 16:50

Agree exactly... I just forget about multiple recipients and there themes-languages

Code that generate this blocks are lightweigh so caching is optional

RTBS patch from #14

#16

Berdir - March 7, 2009 - 00:02
Title:Block cache should be BLOCK_CACHE_PER_USER» Block cache should be BLOCK_NO_CACHE

just updating the title..

#17

andypost - April 15, 2009 - 04:30

Just reroll against current state

AttachmentSize
privatemsg.block_cache.patch 1.66 KB

#18

litwol - June 8, 2009 - 14:28
Status:needs review» fixed

Committed

#19

System Message - June 22, 2009 - 14:30
Status:fixed» closed

Automatically closed -- issue fixed for 2 weeks with no activity.

 
 

Drupal is a registered trademark of Dries Buytaert.