Posted by mikeytown2 on May 5, 2009 at 5:38am
| 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
#2
#328126: Make Boost's caching views-aware
#3
I really like this quote, as it pertains to boost
#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
Forgot about linking to this
#479942: on node update, update associated term page caches as well
#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
On node update, flush associated term page caches as well. Works with view's
taxonomy/term/%path as well!#8
Added a setting in case you don't want this to happen.
#9
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_thiscolumn 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_thiscolumn. 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 likenid#30, nid#31, nid#32; search forLIKE 'nid#30'to get all pages that contain the node with an nid of 30.Thoughts, hints, ideas?
#11
This is postponed until someone comes up with a smarter idea or a way to get the nid out of view/panels.
#12
#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_callbackpage_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, 200views_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
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
Future reference for panels
http://api.drupalecommerce.org/api/function/page_manager_page_execute/6
Hit one more snag, hopefully this is the last road block.
#598942: _boost_get_menu_router() should use menu_get_item() instead of custom code
#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 belowbase_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).
#19
Code insertion point
http://api.lullabot.com/hook_views_pre_render
Looking towards the future
http://groups.drupal.org/node/17644
http://drupal.org/project/materialized_view
http://bazaar.launchpad.net/~davidstrauss/mv/DRUPAL-6--1/files
#20
Just need to store this in a db table. This rocks. Need to handle other objects besides nodes; one step at a time...
<?phpfunction 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
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
#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
committed; now I need to get this working with node creation.
#24
#25
committed
Panels is next
http://api.drupalecommerce.org/api/function/page_manager_page_execute/6
#26
#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:
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
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).
#32
committed
#33
Automatically closed -- issue fixed for 2 weeks with no activity.