I'm the author of the 7.x-2.x branch of authcache. Today I conducted a little experiment in order to explore the possibilities of using boost as the caching backend for authcache (instead of the drupal caching layer). At a first glance the integration seems to be relatively straight forward. The approach is heavily inspired by the stuff I found over at #629520: Cache by theme for mobile sites..
In the following I'll explain the settings and changes I've used.
.htaccess
### BOOST START ###
# Authcache basic exclusion rules (see authcache.inc)
RewriteCond %{REQUEST_METHOD} !^(GET|HEAD)$
RewriteRule .* - [S=4]
# Authenticated user with authcache cookie=69083ee
RewriteCond %{HTTP_COOKIE} SESS79cbb35a3d5a3cef4d68411a1e238ad8
RewriteCond %{HTTP_COOKIE} authcache=69083ee
RewriteRule .* - [S=2,E=boostpath:69083ee]
# Anonymous user
RewriteCond %{HTTP_COOKIE} !SESS79cbb35a3d5a3cef4d68411a1e238ad8
RewriteCond %{HTTP_COOKIE} !authcache
RewriteRule .* - [S=1,E=boostpath:normal]
# No match in previous conditions, skip delivery from cache
RewriteRule .* - [S=1]
# Deliver HTML from cache
RewriteCond %{DOCUMENT_ROOT}/cache/%{ENV:boostpath}/localhost%{REQUEST_URI}_%{QUERY_STRING}\.html -s
RewriteRule .* cache/%{ENV:boostpath}/localhost%{REQUEST_URI}_%{QUERY_STRING}\.html [L,T=text/html]
### BOOST END ###
Regarding the basic exclusion rules: Note that in authcache we follow the approach to simply avoid storing anything to the cache we do not want to deliver to the user afterwards. Therefore there are only three basic exclusion rules. Only the one given is really relevant for this POC.
I suggest checking against the session-cookie instead of relying on a custom one. The name of the session cookie can be retrieved using session_name(). Authcache basically generates a cookie-value depending on the combination of roles a user has. The cookie is not present for users which have roles which are not authcache-enabled. Therefore caching for an logged-in user is possible when a session is open and the authcache-cookie has an expected value.
On the other hand caching for anonymous users is possible when both of the cookies mentioned above are absent.
When we have some unexpected cookie-state, we give authcache a chance to fix the browser by performing a full bootstrap.
This is essentially the same thing which happens in authcache.inc
settings.php
if (isset($_SERVER['boostpath'])) {
$conf['boost_normal_dir'] = $_SERVER['boostpath'];
}
$conf['cache_backends'][] = 'sites/all/modules/authcache/modules/authcache_ajax/authcache_ajax.inc';
$conf['cache_backends'][] = 'sites/all/modules/authcache/authcache.inc';
First we grab the value set in .htaccess and simply use that to redirect the boost-directory. Last two lines are boilerplate authcache requirements.
boost.module
diff --git a/boost.module b/boost.module
index d4825ad..a048e8f 100644
--- a/boost.module
+++ b/boost.module
@@ -322,7 +322,7 @@ function boost_exit($destination = NULL) {
// Attach extension to filename.
$_boost['filename'] .= '.' . $_boost['matched_header_info']['extension'];
// Write to file.
- boost_write_file($_boost['filename'], $data);
+ // boost_write_file($_boost['filename'], $data);
// Gzip support.
if (BOOST_GZIP && $_boost['matched_header_info']['gzip']) {
Prevent boost from actually writing cache files - quick and dirty.
authcache.inc
diff --git a/authcache.inc b/authcache.inc
index 5759b92..9c1a2ac 100644
--- a/authcache.inc
+++ b/authcache.inc
@@ -17,10 +17,10 @@
*/
// Attempt to deliver the page from cache
-$delivered = authcacheinc_retrieve_cache_page();
-if ($delivered) {
- exit;
-}
+// $delivered = authcacheinc_retrieve_cache_page();
+// if ($delivered) {
+// exit;
+// }
/**
* Send cached page to browser, if found.
Disable delivery of cached pages from drupal core caching system.
authcache.module
diff --git a/authcache.module b/authcache.module
index 88c8ba9..f497208 100644
--- a/authcache.module
+++ b/authcache.module
@@ -761,6 +761,10 @@ function authcache_page_set_cache() {
}
if ($cache->data['body']) {
+ // BEGIN authcache-boost experiment: remember uncompressed body
+ $data = $cache->data['body'];
+ // END authcache-boost experiment
+
if (variable_get('page_compression', TRUE) && extension_loaded('zlib')) {
$cache->data['body'] = gzencode($cache->data['body'], 9, FORCE_GZIP);
}
@@ -769,7 +773,36 @@ function authcache_page_set_cache() {
drupal_alter('authcache_cache', $cache);
cache_set($cache->cid, $cache->data, 'cache_page', $cache->expire);
+
+ // BEGIN authcache-boost experiment: Save page to boost cache
+ $_boost = boost_transform_url();
+
+ // Get header info.
+ $_boost['header_info'] = boost_get_header_info();
+ $_boost['matched_header_info'] = boost_match_header_attributes($_boost['header_info']);
+ if ($_boost['matched_header_info']['enabled'] === FALSE) {
+ return;
+ }
+
+ // Add note to bottom of content if possible.
+ if ($_boost['matched_header_info']['comment_start'] && $_boost['matched_header_info']['comment_end']) {
+ $expire = $_boost['matched_header_info']['lifetime_max'];
+ $cached_at = date('Y-m-d H:i:s', REQUEST_TIME);
+ $expires_at = date('Y-m-d H:i:s', REQUEST_TIME + $expire);
+ $note = "\n" . $_boost['matched_header_info']['comment_start'] . 'Page cached by Authcache-Boost @ ' . $cached_at . ', expires @ ' . $expires_at . ', lifetime ' . format_interval($expire) . $_boost['matched_header_info']['comment_end'];
+ $data .= $note;
+ }
+
+ // Write data to a file.
+ if ($_boost['filename']) {
+ // Attach extension to filename.
+ $_boost['filename'] .= '.' . $_boost['matched_header_info']['extension'];
+ // Write to file.
+ boost_write_file($_boost['filename'], $data);
+ }
+ // END authcache-boost experiment
}
+
return $cache;
}
}
Copy/paste from boost_exit into authcache_page_set_cache
Conclusion
In order to better integrate authcache and boost, I think the following things are necessary:
- Allow to swap out the default drupal caching backend with another implementation in authcache
- Extract the part responsible for actually writing a cached request from
boost_exitinto a separate function - Provide a way to enumerate all possible values of the authcache-cookie
- Extend the .htaccess rules generator
I do not understand boost very well. Especially I have no idea on how the changes will affect cache expiration and crawling and stuff like that. Therefore I'd really appreciate if some boost-experts chime in and point out the relevant things. What do you think?
Comments
Comment #1
znerol commentedOk, I addressed everything on the authcache-side of the equation. There is now a new submodule
authcache_boostover in authcache 7.x-2.x branch that will use boost as an authcache backend. However the integration code could be prettier if some boost-logic would be broken out from hooks into separate functions.Code lives here, comments welcome: authcache_boost
Comment #2
Anonymous (not verified) commentedI meant to address this earlier, I mainly do support and patch on the forums, BGM is in charge and it would be best to talk to him, there was a rumour that boost could be integrated into drupal 8 at one point and he is best placed to guide the direction. (but he's very busy too)
Philip.
Comment #3
znerol commentedCurrently
authcache_boostrequires the following patch for boost: #1942848: Introduce optional Vary Cookie header in generated .htaccess files in cache directory. Otherwise stale content may be displayed after login/logout.Comment #4
znerol commentedAs soon as the patch in #1949504: Support multiple cache directories lands, I'll be able to remove half of the hacks from
authcache_boost.Comment #4.0
znerol commentedFix skip-number of first rewrite rule
Comment #5
taote commentedAny updates on this issue?
Comment #6
Mario Baron commentedI have been a Boost fan for a long time now and have it installed on all my sites. However, I had it installed on a commerce site and it really did not work very well because Shopping cart block is dynamic. So if a user add's a product to the cart and then wonders of to another page (features page for example) they have no way of getting to their cart unless they know the exact url /cart and I guess this can have an impact on sales as I can see a lot of carts that did not complete the purchase on my site.
So, I turned to Authcache + Filecache now and its working but I have to say its not giving me same performance increase as I had with Boost.
I am testing the unsupported Authcache Boost backend storage on my local server but there is a lot of guesswork on my part since there is a lack of documentation for boost+authcache integration on project page as well as on https://drupal.org/node/2160133
Authcahe+Boost could be a really good "marriage" and I can see @znerol is contributing patches to boost to make this happen but, it seems like there is a lack of interest or time to make this happen on Boost end.
@znerol
Could you please document all the required patches and settings.php configuration for Boost as Authcache back end storage somewhere? I would be really interested in testing this integration but right now I am guided by bits of information and patches scattered across the issue queues...
Thanks for all your efforts Authcache + Boost integration is one the most exciting new I've seen in a while
Comment #7
yannisc commented@Mario Baron for the usecase you describe, maybe a better fit would be ajax blocks (https://drupal.org/project/ajaxblocks) for the cart block. I use it in many commerce sites with boost and works really well.
Comment #8
Mario Baron commented@yannisc
Thanks for your advice.
Which version of ajaxblocks are you using? The reason I am asking is because I just tried it now and it isn't working for some reason. After first tests it even stopped boost from working properly and the ajaxblocks wasn't working at all. I tried version 1.3 and when that didn't work I tried the latest dev and still no joy there.
The only block I need to be dynamic is the View: Shopping Cart Block drupal commerce. I checked Ajaxblocks issue queue for solutions but it seems only issues are being reported and no fix https://drupal.org/node/1348918
Since you got it working on your commerce sites I'd be really interested in how you got it to work. Can you share your settings for both Boost and Block which is being loaded using ajaxblocks please?
I really need to get this working asap so thanks in advance for anyone with a solution
Comment #9
yannisc commentedI use the regular settings for both of them and had not problem. The only difference in settings was to set ajax blocks to be loaded for anonymous users for both cached and non-cached pages.
Comment #10
Mario Baron commentedThanks yannisc enabling ajax block to be loaded for both cached and non-cached pages does the trick.
One thing I noticed thou...
Boost will cache all pages up until the point when I add something to cart. At that point my ajax block works great on all pages however visiting any new pages after that kills boost caching for those pages. The pages I visited before adding to cart are still being served from boost cache.
Is this a normal behaviour?
using Boost 7.x-1.0-beta2 and Ajax blocks 7.x-1.3
Comment #11
summit commentedHi, wanting to use boost for Drupal Commerce also, interested in answers for #10: https://drupal.org/node/1932444#comment-8639859
Greetings, Martijn
Comment #12
Anonymous (not verified) commentedThe way boost works is that it caches for anonymous users and no https pages. It take the output from Drupal just before it is presented to the browser and then saves it as an html file. This file is then given in preference to going through drupal and PHP by a set of rewrite rules.
The reason that boost stops serving cached pages is either,
This is a good thing. In fact I would not recommend boost on any commerce site because of the following, for anonymous users boost will store stock levels, colours, prices as a static html page that will only expire after an hour minimum leading to customer confusion if then it suddenly goes out of stock. As for allowing boost to work with authcache, that is not going to happen, imagine that the boost rules did not apply so that then you submitted a form to be presented with a static shopping cart from someone else that surfed an hour before. Your customer would be able to do nothing, the cart would not submit as the form would have expired with it's unique id. Possibly the form could side of things will change but it would require to be ajaxed and linked into a session that did not set the DRUPAL_UID cookie. You would have better luck in persuading authcache to nominate specific pages to be made static.