Catalyst-Plugin-PageCache
view release on metacpan or search on metacpan
Revision history for Perl extension Catalyst::Plugin::PageCache
0.31 2010-11-09
- Fixed config in test apps to silence warnings from tests.
- Fixed module version number.
- Require File::Path 2.07.
- Made t/15busy_lock.t test more robust
0.30 2010-11-03 16:03 r13688
- Updated tests to use Cache::FileCache instead of the deprecated ::FileCache.
Report and patch by Rod Taylor, RT#53304 & RT#47373.
- Fixed t/04critic.t to not fail if Test::Perl::Critic is not installed.
- Updated test app code to avoid deprecated constructs.
- Only serve GET and HEAD requests (instead of all except POST). RT#53307.
- Allow key_maker to be the name of a method to be called on $c. RT#53529.
- Assorted performance optimizations.
- Add cache_dispatch_hook and cache_finalize_hook to config. RT#53503.
0.22 2009-06-25 10:38:00
- Update to use MRO::Compat
0.21 2008-10-02 10:45:00
- Check for FileCache in new test to avoid test failures.
0.20 2008-10-02 00:15:00
- Config option 'cache_headers' to cache HTTP headers. This is needed
if operating behind edge caches such as Akamai. (Chris Alef)
- Config option 'busy_lock' borrowed from Mason, avoids the "dog-pile"
effect where many concurrent requests can generate and cache the same
page. See the documentation for details.
- The ability to call clear_cached_page can be disabled to improve
performance (a cache index will not be created/updated).
0.19 2008-08-22 13:00:00
- Change config namespace to $c->config->{'Plugin::PageCache'}, old
namespace will still continue to work.
- key_maker method, allows custom cache keys to be used. (Martin Ellison)
t/05expires.t
t/06auto_cache.t
t/07set_http_headers.t
t/08params.t
t/09datetime.t
t/10options.t
t/11nocache.t
t/12i18n.t
t/13cachehook.t
t/14keymaker.t
t/15busy_lock.t
t/lib/TestApp.pm
t/lib/TestApp/Controller/Cache.pm
t/lib/TestAppI18N.pm
t/lib/TestAppI18N/Controller/Cache.pm
t/lib/TestAppI18N/I18N/en.pm
t/lib/TestAppI18N/I18N/es.pm
or as a regex: '/view/.*'
disable_index => 1
In order to support the "clear_cached_page" method, PageCache keeps an
index of all cached pages. If you don't intend to use
"clear_cached_page", you may enable this config option to avoid the
overhead of creating and updating the cache index. This option is
disabled by default.
busy_lock => 10
On a high traffic site where page re-generation may take many seconds, a
common problem encountered is the "dog-pile" effect, where many
concurrent connections all hit a page where the cache has expired and
all perform the same expensive operation to rebuild the cache. To
prevent this situation, you can set the busy_lock option to the maximum
number of seconds any of your pages can be expected to take to rebuild
the cache. Then, when the cache expires, the first request will rebuild
the cache while also extending the expiration time by the number of
seconds specified, allowing other requests that arrive before the cache
has been rebuilt to use the previously cached page. This option is
disabled by default.
debug => 1
This will print additional debugging information to the Catalyst log.
lib/Catalyst/Plugin/PageCache.pm view on Meta::CPAN
unless my $key = $c->_get_page_cache_key;
my $cache = $c->cache; # curry the cache just once, here
return $c->next::method(@_)
unless my $data = $cache->get( $key );
# Time to remove page from cache?
if ( $data->{expire_time} && $data->{expire_time} <= time ) {
if ( my $busy_lock = $pc_config->{busy_lock} ) {
# Extend the expiration time for others while
# this caller refreshes the cache
$data->{expire_time} = time() + $busy_lock;
$cache->set( $key, $data );
$c->log->debug( "$key has expired, being refreshed for $busy_lock seconds" )
if ($pc_config->{debug});
}
else {
$c->log->debug( "Expiring $key from page cache" )
if ($pc_config->{debug});
$cache->remove( $key );
if ( my $index_page_key = $pc_config->{index_page_key} ) {
my $index = $cache->get( $index_page_key ) || {};
lib/Catalyst/Plugin/PageCache.pm view on Meta::CPAN
if ( $c->config->{page_cache} and !$c->config->{'Plugin::PageCache'} ) {
$c->config->{'Plugin::PageCache'} = delete $c->config->{page_cache};
}
my $pc_config = $c->config->{'Plugin::PageCache'} ||= {};
$pc_config->{auto_cache} ||= [];
$pc_config->{expires} ||= 60 * 5;
$pc_config->{cache_headers} ||= 0;
$pc_config->{set_http_headers} ||= 0;
$pc_config->{busy_lock} ||= 0;
$pc_config->{debug} ||= $c->debug;
# default the page key to include the app name to give some measure
# of protection if the cache doesn't have a namespace set.
$pc_config->{index_page_key} = "$c._page_cache_index"
unless defined $pc_config->{index_page_key};
if (not defined $pc_config->{disable_index}) {
warn "Plugin::PageCache config does not include disable_index, which currently defaults false but may default true in future\n";
$pc_config->{disable_index} = 0;
lib/Catalyst/Plugin/PageCache.pm view on Meta::CPAN
If you don't intend to use C<clear_cached_page>, you should enable this config
option to avoid the overhead of creating and updating the cache index. This
option is currently disabled (i.e. the page index is enabled) by default but
that may change in a future release.
index_page_key => '...'
The key string used for the index, Defaults to a string that includes the name
of the Catalyst app class.
busy_lock => 10
On a high traffic site where page re-generation may take many seconds, a common
problem encountered is the "dog-pile" effect, where many concurrent connections all
hit a page where the cache has expired and all perform the same expensive operation
to rebuild the cache. To prevent this situation, you can set the busy_lock option
to the maximum number of seconds any of your pages can be expected to take to
rebuild the cache. Then, when the cache expires, the first request will rebuild the
cache while also extending the expiration time by the number of seconds specified,
allowing other requests that arrive before the cache has been rebuilt to use the
previously cached page. This option is disabled by default.
debug => 1
This will print additional debugging information to the Catalyst log. You will
need to have -Debug enabled to see these messages.
t/15busy_lock.t view on Meta::CPAN
plan skip_all => "needs Catalyst::Plugin::Cache for testing: $@"
if not eval "use Catalyst::Plugin::Cache; 1";
plan skip_all => 'Cannot run this test on Windows' # XXX still true?
if $^O =~ /Win32/;
plan tests => 7;
use Catalyst::Test 'TestApp';
TestApp->config->{'Plugin::PageCache'}->{busy_lock} = 5;
ok( request('http://host1/cache/set_count/0', 'request ok' ) );
# Request a slow page once, to cache it
ok( my $res = request('http://localhost/cache/busy'), 'request ok' );
is( $res->content, 1, 'count is 1' );
sleep 1; # delay so cached page will have expired
my $cache_time = time + 1;
1 while time < $cache_time; # spin till clock ticks to make test more robust
# Fork, parent requests slow page. After parent requests, child
# requests, and gets cached page while parent is rebuilding cache
if ( my $pid = fork ) {
# parent
my $start = time();
ok( $res = request('http://localhost/cache/busy'), 'parent request ok' );
cmp_ok( time() - $start, '>=', 1, 'slow parent response ok' );
is( $res->content, 2, 'parent generated new response' );
# Get status from child, since it can't print 'ok' messages without
# confusing Test::More
wait;
is( $? >> 8, 0, "fast child response ($?)" );
}
else {
# child
sleep 1; # delay to ensure parent makes request first
# but not long enough for the parent to have finished
my $start = time();
$res = request('http://localhost/cache/busy');
my $dur = time() - $start;
my $errors = 0;
my $content = $res->content;
if ($content ne '1') {
warn "Child didn't get cached response ($content)\n";
++$errors;
}
if ($dur >= 1) {
t/lib/TestApp/Controller/Cache.pm view on Meta::CPAN
$c->cache_page(
last_modified => time,
expires => 0,
cache_seconds => 20,
);
$c->res->output( $c->config->{counter} );
}
sub busy : Local {
my ( $self, $c ) = @_;
$c->cache_page( 1 );
sleep 2;
$c->res->output( $c->config->{counter} );
}
sub get_key : Local {
( run in 0.443 second using v1.01-cache-2.11-cpan-87723dcf8b7 )