The Different ways I Can Cache You Page
Overview
Page caching can happen at application level via a cache plugin such as Catalyst::Plugin::Cache with a backend such as Cache::FastMmap. It can also be done on the web server or via a proxy. This paper will examine PageCache Catalyst plugin, NGINX web server and Varnish Proxy cache control techniques.
It’s important to highlight the facets of caching. On one hand, deciding what to put in the cache (and where to store it). While another other hand concerns with when to pull (read) from the cache (and where to get it from.
- set cache
- get cache
Set Cache
We need to set the cache before we can get anything beside nothing. The cache can actually be set at different places in the application.
- PageCache Catalyst plugin
- NGINX expires directive in configuration
- Varnish VCL
Further yet, setting a cache may be putting an item into a cache or setting the header of the item perform Cache-Control.
PageCache
Backend Cache
One way to cache MojoMojo is to do so at the application level. One specifies which pages to cache and for how long they should be in the cache.
Headers for Caching Middleware
One can also set some headers for Cache-Control such as max-age or no-cache
Application Cache Configuration
use Catalyst qw/ # Other Modules Before PageCache /; MojoMojo->config( 'Plugin::PageCache' => { expires => 300, set_http_headers => 0, auto_check_user => 1, auto_cache => [ '/.*', ], key_maker => sub { my $c = shift; return $c->stash->{path} . '.' . $c->req->path; }, debug => 0 , cache_hook => 'cache_hook' } );
Notes about cache configuration keys:
- expires - how long a page is cached before being rebuilt
- set_http_headers - can set Cache-Control header such as ‘max-age’
- auto_check_user - don’t cache pages when a user is logged in1
- auto_cache - specifies uri’s to automatically cache (takes regex)
- key_maker - over method to create unique key for cache items
- debug - show if a page is in the cache (needs Catalyst Debug on, -d)
- cache_hook - a callback to decide whether a page should be cached or not
where the cache_hook is a method name that determines (boolean) whether a page is to be cached or not. Thus this is a application wide approach.
cache_hook
The guidelines for the cache_hook are to cache unless
- $c->user_exists (auto_check_user)
- CATALYST_NOCACHE is set
- path is excluded from cache_ie_list
indirect method
One cache_hook method for MojoMojo currently looks like:
sub cache_hook { my ( $c ) = @_; if ( $c->user_exists || $ENV{CATALYST_NOCACHE} || ! $c->cache_ie_list->evaluate($c->req->path) ) { return 0; # Don't cache } return 1; # Cache }
Notice we don’t cache when user exists (similar if not the same as auto_check_user) nor when and environment variable has been set which can turn off PageCache all-togther.
direct method
sub cache_hook { my ( $c ) = @_; return !$c->user_exists && !$ENV{CATALYST_NOCACHE} && $c->cache_ie_list->evaluate($c->req->path); }
cache_ie_list
URI’s are either included or excluded from the cache.
my $ie; $ie = Algorithm::IncludeExclude->new; # Start by including all page for caching $ie->include(); # static files will be handled via web server or proxy cache control. $ie->exclude(qr/static/); $ie->exclude('login'); $ie->exclude('logout'); $ie->exclude('edit'); #$ie->exclude('list'); #$ie->exclude('recent'); sub cache_ie_list { return $ie; }
Cache in Controller
Besides application wide controller, one can cache at the level of a controller action ala:
sub view : Global { my ( $self, $c, $path ) = @_; $c->cache_page( last_modified => $last_modified, cache_seconds => 24 * 60 * 60, expires => 30, );
which separates control of page cache storage time and the header expiration date (which can be used by proxies).
Firebug Info
Let’s see what information (headers in particular) Firebug in FireFox will show us.
Catalyst Built-In Server - set_http_headers => 0 (OFF)
Capçaleres de la resposta
X-PageCache Catalyst
Capçaleres de la sol·licitud
Cookie mojomojo_session=43b7b9dc41f21d7219051d2343d8cc66b6ca9a48; split_edit=1
Catalyst Built-In Server - set_http_headers => 1 (ON)
Capçaleres de la resposta
Cache-Control max-age=251 X-PageCache Catalyst
Capçaleres de la sol·licitud
Cookie mojomojo_session=43b7b9dc41f21d7219051d2343d8cc66b6ca9a48; split_edit=1
NGINX Server - set_http_headers => 0 (OFF)
Capçaleres de la resposta
Server nginx/0.6.32 X-PageCache Catalyst
Capçaleres de la sol·licitud
Cookie mojomojo_session=43b7b9dc41f21d7219051d2343d8cc66b6ca9a48; split_edit=1
NGINX Server - set_http_headers => 1 (ON)
Capçaleres de la resposta
Server nginx/0.6.32 Cache-Control max-age=251 X-PageCache Catalyst
Capçaleres de la sol·licitud
Cookie mojomojo_session=43b7b9dc41f21d7219051d2343d8cc66b6ca9a48; split_edit=1
1 This doesn’t prevent a logged in user from receiving a cached page. It just that they won’t cause any pages to be cached.
Showing changes from previous revision. Removed | Added
