Download & Extend

Hook for panel node types - expiration of static cache; panel containing multiple nodes

Project:Boost
Version:6.x-1.x-dev
Component:Expiration logic
Category:feature request
Priority:normal
Assigned:Unassigned
Status:closed (fixed)

Issue Summary

Right now, boost handles the dynamic expatriation of comments (boost_comment()), nodes (boost_nodeapi()) and user (boost_user()) pages.

Taxonomy (boost_taxonomy()) is in there, but does nothing. The other types of content are:

  • Views
  • Panels

Anything else?

Comments

#1

Title:Hooks for other content types - expatriation of static cache» Hooks for other content types - expiration of static cache

#2

#3

I really like this quote, as it pertains to boost

"There are only two hard things in Computer Science: cache invalidation and naming things" - Phil Karlton

#4

code to make this smarter in the long run for the DB. Stolen from http://api.drupal.org/api/function/menu_get_item

<?php
$path
= $_GET['q'];
$original_map = arg(NULL, $path);
$parts = array_slice($original_map, 0, MENU_MAX_PARTS);
list(
$ancestors, $placeholders) = menu_get_ancestors($parts);
$router_item = db_fetch_array(db_query_range('SELECT page_callback FROM {menu_router} WHERE path IN ('. implode (',', $placeholders) .') ORDER BY fit DESC', $ancestors, 0, 1));
echo
$router_item['page_callback'];
?>

#5

#6

in order to support killing term pages, adding in a content-id column to the boost database table would be the way to go.

#7

Status:active» needs review

On node update, flush associated term page caches as well. Works with view's taxonomy/term/% path as well!

AttachmentSize
boost-453908.patch 1.47 KB

#8

Added a setting in case you don't want this to happen.

AttachmentSize
boost-453908.1.patch 3.17 KB

#9

Status:needs review» active

committed.

Next:
Support panels that embed multiple nodes.
Views aware.

#10

In order to support views and panels, we need to create a page_contains_this column in the database. A node has no idea where it is being used, so we need to be able to query for it in other content types; which means the data that will be stored has to be easily query-able and it has to contain multiple values. A table inside of a table is kinda whats needed.

node of content type blog with a nid of 30
This can be used in multiple views & in multiple panels. node/% & taxonomy/term/% overrides are already taken care of so this will try to deal with getting the nid out of the view.
http://api.lullabot.com/ isn't much help since views & panels don't have a an api to get the nid.

If one can easily get the nid out of the view then those values would be stored in the page_contains_this column. Anyone have any good suggestions on how to hold 1 or 10,000 nid's in the database so all effected pages can be flushed when that node changes? My current idea is to store a text blob, do a like query on it and store the NID's like
nid#30, nid#31, nid#32; search for LIKE 'nid#30' to get all pages that contain the node with an nid of 30.

Thoughts, hints, ideas?

#11

Status:active» postponed

This is postponed until someone comes up with a smarter idea or a way to get the nid out of view/panels.

#12

Title:Hooks for other content types - expiration of static cache» Hooks for other content types (views & panels) - expiration of static cache

#13

create a index in the boost_cache table (call it uid). Create a new table called boost_reference; works similar to term table. 1 entry is equal to 1 reference.
Add a uid index to the boost_reference table.
boost_reference table has 5 columns.

page_callback
page_arguments
page_id
uid - links to the nid in the boost_cache table that is related.
nid - nid (optional)

So for a view with 6 nodes...

views_page, front, 5, 55, 200
views_page, front, 5, 56, 202
views_page, front, 5, 57, 204
views_page, front, 5, 58, 206
views_page, front, 5, 59, 208
views_page, front, 5, 60, 210

When a node is expired, it looks for it's own uid in the boost_reference table. Given that uid it gets the page_callback, page_arguments, page_id info. It then searches for all matches in boost_cache (WHERE = AND = AND =) and flushes them. So if the node with the boost_cache uid = 56; that node could be on multiple views. This would find all those views, and flush them (html, ajax, xml). Can also lookup the nid directly, if node was flushed.

#14

Title:Hooks for other content types (views & panels) - expiration of static cache» Hooks for other content types (views) - expiration of static cache (panels still postponed)
Status:postponed» active

http://drupal.org/node/488982 - How to access a view in a different module
http://state68.com/node/2 - Accessing Views from a custom module
http://drupal.org/node/342132 - Get the result a view creates
http://www.broadlatitude.com/blogs/matt/content/drupal-tip-never-query-c... - Drupal Tip: Never query CCK tables directly again

#15

md5 url and filename has to happen, can use this as a key. #575386: Table boost_cache fields size restrict the length of possible URLs

#16

final piece of the puzzle is in place... #598490: Be able to expire all views, but not all nodes; ect...

#17

#18

Getting somewhere...

Get list of nodes for in the current view

<?php
  $view
= views_get_page_view();
  if (!
is_null($view)) {
    foreach (
$view->view->result as $item) {
     
$item->nid;
    }
  }
?>

Flush all nodes on this view

<?php
  $view
= views_get_page_view();
  if (!
is_null($view)) {
   
$data = array();
    foreach (
$view->view->result as $item) {
     
$node = node_load($item->nid);
     
$data[] = array('base_dir' => BOOST_FILE_PATH, 'page_callback' => 'node', 'page_type' => $node->type, 'page_id' => $item->nid);
    }
   
boost_cache_expire_router($data);
  }
?>

This means I need to store these 3 router items in the database. Node will look for it's self based a match for these 3 items, if a match is found then this view is expired from the cache. So to go along with this, I need the 3 router items of this view in the DB as well. Create a hash of all 7 items for the Primary Key (3 + 3 + 1).

Database structure

hash = MD5 of the 7 items below
base_dir - needed for multisite support
parent_page_callback - view in this case
parent_page_type - views name
parent_page_id - views display
child_page_callback - node in this case
child_page_type - node type
child_page_id - node id

When node gets updated, looks for self in above table (child); gets all matches and flushes the parents (cached views).

#20

Just need to store this in a db table. This rocks. Need to handle other objects besides nodes; one step at a time...

<?php
function boost_views_pre_render(&$view) {
  if (!
is_null($view)) {
   
$router_item = isset($GLOBALS['_boost_router_item']) ? $GLOBALS['_boost_router_item'] : _boost_get_menu_router(); // Parrent Data
   
$data = array();
    foreach (
$view->result as $item) {
     
$node = node_load($item->nid);
     
$data[] = array('base_dir' => BOOST_FILE_PATH, 'page_callback' => 'node', 'page_type' => $node->type, 'page_id' => $item->nid); // Child Data
   
}
   
boost_cache_expire_router($data); // Example for data exit point.
 
}
}
?>

#21

Status:active» needs review

I may want to do a define for $GLOBALS['_boost_router_item']
Also would like to have the views hook work with Faceted Search module
Flush on node creation is the next step

AttachmentSize
boost-453908.patch 15.85 KB

#22

In order to flush the correct views on node creation, a list of all cached views is needed. Use that to recreate all views that are cached & see what views contain the new node. View needs to be tested with UID=0.

Get list of all cached views

SELECT * FROM {boost_cache} WHERE page_callback = 'view'

Build View... something like this

<?php
$view
= views_get_view($viewname);
$view->set_display($display_id);
$view->pre_execute();
$view->execute();
?>

#23

Status:needs review» active

committed; now I need to get this working with node creation.

#24

Status:active» needs review
AttachmentSize
boost-453908.patch 4.36 KB

#25

Title:Hooks for other content types (views) - expiration of static cache (panels still postponed)» Hooks for panels - expiration of static cache
Status:needs review» active

committed

Panels is next
http://api.drupalecommerce.org/api/function/page_manager_page_execute/6

#26

Title:Hooks for panels - expiration of static cache» Hook for panel node types - expiration of static cache; panel containing multiple nodes

#27

Here is a naive observation, so take it for what it's worth.

Nodes can be rendered in views in many ways that do not always have a router table entry, such as views which render into blocks, or views which are consumed directly by modules like Quicktab.

Why not have the node record the fact that it has rendered itself within a view by:

  • Putting code in hook_nodeapi (or somewhere better, maybe even a preprocessing function) which...
  • Looks at the $node->view argument (which will be set whenever the node is rendered inside a view), and...
  • If caching is enabled in the view, make a database entry with the nid and view name...

Then, no matter why or how a node gets rendered, whether in a block or other context, it will make a record of the fact that it was rendered, and there will be a simple list for each node of which views contain cached versions of themselves.

Caveat: I am just a random passer-by here! Your way may be best! But, just throwing it out because it was the first thing that occurred to me.

#28

Any progress on panels integration?

#29

none but this looks like it might be of some help
http://drupal.org/node/362065

Panels support is only needed if you have a panel page. If your using "Node template" then boost will work as expected.

#30

subscribing

#31

Status:active» needs review

took some hints from #362065: Panels Override Support to get this working. Looking at the calling function http://drupalcontrib.org/api/function/ctools_context_handler_render/6 helped the most though (i needed $handler).

AttachmentSize
boost-453908.patch 3.28 KB

#32

Status:needs review» fixed

committed

#33

Status:fixed» closed (fixed)

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

nobody click here