Disabling Caching Per Node Type

Events happening in the community are now at Drupal community events on www.drupal.org.
markwk's picture

I'm currently using omega8 hosting with nginx and all that sped-up goodness. I'm developing a bunch of stuff with node.js integration now, and I have a chat node that needs to have caching disabled. Basically a user can chat live and all that via node.js backend but when they reload the page it's pulling the cached page a not the recent chat.

So how would one go about disabling caching for a single node type, for example?

I saw something about: header('X-Accel-Expires: 0'); in the nginx google group forums but I'm really sure how or where to apply this in my module.

Comments

omega8cc Hosting

Peter Bowey's picture

Method 1:

In your Drupal settings.php you will have something like this (my shown version will differ from yours - but will suite for illustration purposes):

<?php
//
//  X-Accel-Expires: Sets when to expire the file in the internal Nginx cache, if one is used.
//  We emit an "X-Accel-Expires: 0" header when a user is logged in or has taken actions that should cause them to get a customized page
//
if (isset($<em>SERVER['HTTP_HOST'])) {                                             // If HTTP_HOST is not set, client is either old (HTTP 1.0) or has made a request directly to our web site's IP
 
if (preg_match("/\/(?:files\/advagg</em>|files\/styles|files\/imagecache)/", $<em>SERVER['REQUEST_URI'])) {               // if static files (via: advagg || imagecache || files || styles|files)
   
header('X-Accel-Expires: 0');                                                                                           // do not cache it on the Nginx cache level
 
}
  if (isset(
$_SERVER['REQUEST_TIME']) && isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['HTTP_USER_AGENT']) &&            // If timestamp for start of the request + User-agent
     
!preg_match("/\/(?:files\/advagg</em>|files\/styles|files\/imagecache)/", $_SERVER['REQUEST_URI'])) {                  // + NOT static files
   
$identity = $_SERVER['REQUEST_TIME'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_HOST'] . $_SERVER['HTTP_USER_AGENT'];   // create and ID
   
$identity = 'BOND'. md5("$identity");

   
$test_sess_name = 'SESS'. md5($cookie_domain);                                                                          // create a session cookie

   
if (preg_match("/^\/(?:user|admin|logout)/", $_SERVER['REQUEST_URI']) ||
       
preg_match("/\/(?:node\/[0-9]+\/edit|node\/add|comment\/reply|approve|users)/", $_SERVER['REQUEST_URI'])) {         // Admin or User or dynamics
     
header('X-Accel-Expires: 0');                                                                                         // do not cache it on the Nginx cache level
     
if (isset($_COOKIE[$test_sess_name]) && !isset($_COOKIE['OctopusNoCacheID'])) {
       
setcookie('OctopusNoCacheID', $identity, $_SERVER['REQUEST_TIME'] + ('240' + 60), '/', $cookie_domain);
      }
      elseif (!isset(
$_COOKIE[$test_sess_name]) && !isset($_COOKIE['OctopusNoCacheID'])) {
       
setcookie('OctopusNoCacheID', 'NOCACHE' . $identity, $_SERVER['REQUEST_TIME'] + ('240' + 60), '/', $cookie_domain);
      }
    }
    elseif (isset(
$_COOKIE[$test_sess_name]) && !isset($_COOKIE['OctopusCacheID'])) {
     
setcookie('OctopusCacheID', $identity, $_SERVER['REQUEST_TIME'] + ('86400' + 300), '/', $cookie_domain);
     
header('X-Accel-Expires: 300');
    }
    elseif (isset(
$_COOKIE[$test_sess_name]) && isset($_COOKIE['OctopusCacheID'])) {
     
header('X-Accel-Expires: 300');
    }
    elseif (!isset(
$_COOKIE[$test_sess_name]) && isset($_COOKIE['OctopusCacheID'])) {
     
setcookie('OctopusCacheID', 'NOCACHE' . $identity, $_SERVER['REQUEST_TIME'] + ('0' + 60), '/', $cookie_domain);
     
header('X-Accel-Expires: 0');
    }
  }
}
?>

Now, add your node path to this line:
<?php
   
if (preg_match("/^\/(?:user|admin|logout)/", $_SERVER['REQUEST_URI']) ||
       
preg_match("/\/(?:node\/[0-9]+\/edit|node\/add|comment\/reply|approve|users)/", $_SERVER['REQUEST_URI'])) {         // Admin or User or dynamics
?>

Method 2:

To disable Cache integration per site or platform, you have to create an empty directory with the name "cache" (and this shouldn't be a real cache module!), with one empty NO.txt control file inside, so its path will be, for site level: sites/domain.name/modules/cache/NO.txt, or for platform level: sites/all/modules/cache/NO.txt (the upper case in the NO.txt filename matters!) Note that this extra switch will be available starting with 1.0-boa-T-8.8 Edition (not yet released but available in the Barracuda/Octopus HEAD).

Method 3:

to disable Speed Booster system per platform, you have to create an empty directory with the name "ubercart" (unless you have there the real ubercart module already), with one empty README.txt control file inside, so its path will be: sites/all/modules/ubercart/README.txt (the upper case in the README.txt filename matters!). Starting with 1.0-boa-T-8.8 Edition (not yet released but available in the Barracuda/Octopus HEAD) it will be possible to disable Speed Booster system also per site, so the expected path to the control file will be sites/domain.name/modules/ubercart/README.txt.

For further reference, see: http://groups.drupal.org/node/157779

You are correct about the use of header('X-Accel-Expires: 0')

<?php
   
if (preg_match("/^\/(?:user|admin|logout)/", $_SERVER['REQUEST_URI']) ||
       
preg_match("/\/(?:node\/[0-9]+\/edit|node\/add|comment\/reply|approve|users)/", $_SERVER['REQUEST_URI'])) {         // Admin or User or dynamics
     
header('X-Accel-Expires: 0')
?>

X-Accel-Expires=0 to keep nginx from caching..

Reference: see -> http://techminded.net/blog/transparent-cache-in-nginx.html

--
Linux: Web Developer
Peter Bowey Computer Solutions
Australia: GMT+9:30
(¯`·..·[ Peter ]·..·´¯)

Option 4#: From the original

Peter Bowey's picture

Option 4#:

From the original omega8cc archives:

Note: it is not possible to disable the speed booster per module or content type. It is possible to disable it per *path* or per *site* or per *platform*.

You can extend existing exceptions visible in the /data/conf/global.inc file in your custom overrides in /data/conf/override.global.inc (this files must be created).

see: http://drupal.org/node/1157024#comment-4468508

So use something like this:

<?php
# override global settings.php

 
if (preg_match("/^\/(?:quiz|anyname)/", $_SERVER['REQUEST_URI'])) {
   
header('X-Accel-Expires: 0'); // do not cache it in the speed booster
 
}
?>

--
Linux: Web Developer
Peter Bowey Computer Solutions
Australia: GMT+9:30
(¯`·..·[ Peter ]·..·´¯)

It should be possible not

omega8cc's picture

It should be possible not only in the module, but even in your theme - at the top of page.tpl.php, where you could conditionally add the header header('X-Accel-Expires: 0'); only for expected content type, on the fly. It will be not the most elegant (or even correct?), but it should work anyway.

A modest proposal

perusio's picture

I have 0 knowledge about the specifics of omega8cc hosting secrete potion. My suggestion is for you to create a map that sets a variable and use that variable to bust the cache. Or, better yet, configure Nginx to have a location relative to the URIs not to be cached.

location ^~ /do/not/cache/here/ {
  # no caching here
}

You have to define an alias for that using pathauto.

I think there's room for a

brianmercer's picture

I think there's room for a module that sends different cache times (or a zero cache time) for different parts of your site. The single setting under /admin/settings/performance may not fit every page. Sounds like a good use case for ctools page manager.