[Catalyst-commits] r8493 - in trunk/Catalyst-Plugin-PageCache: . lib/Catalyst/Plugin

andyg at dev.catalyst.perl.org andyg at dev.catalyst.perl.org
Wed Oct 1 20:14:39 BST 2008


Author: andyg
Date: 2008-10-01 20:14:38 +0100 (Wed, 01 Oct 2008)
New Revision: 8493

Modified:
   trunk/Catalyst-Plugin-PageCache/Changes
   trunk/Catalyst-Plugin-PageCache/README
   trunk/Catalyst-Plugin-PageCache/lib/Catalyst/Plugin/PageCache.pm
Log:
Config option 'busy_lock' borrowed from Mason to avoid the dog-pile effect

Modified: trunk/Catalyst-Plugin-PageCache/Changes
===================================================================
--- trunk/Catalyst-Plugin-PageCache/Changes	2008-10-01 10:25:02 UTC (rev 8492)
+++ trunk/Catalyst-Plugin-PageCache/Changes	2008-10-01 19:14:38 UTC (rev 8493)
@@ -3,6 +3,9 @@
 0.20    
         - 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).
         

Modified: trunk/Catalyst-Plugin-PageCache/README
===================================================================
--- trunk/Catalyst-Plugin-PageCache/README	2008-10-01 10:25:02 UTC (rev 8492)
+++ trunk/Catalyst-Plugin-PageCache/README	2008-10-01 19:14:38 UTC (rev 8493)
@@ -84,7 +84,8 @@
 
     Enable this value if you need your cached responses to include custom
     HTTP headers set by your application. This may be necessary if you
-    operate behind an edge cache such as Akamai.
+    operate behind an edge cache such as Akamai. This option is disabled by
+    default.
 
         set_http_headers => 1
 
@@ -93,7 +94,7 @@
     further reduce the load on your server. The headers are set in such a
     way that the browser/proxy cache will expire at the same time as your
     cache. The Last-Modified header will be preserved if you have already
-    specified it.
+    specified it. This option is disabled by default.
 
         auto_cache => [
             $uri,
@@ -105,6 +106,28 @@
     the default expiration time. URIs may be specified as absolute: '/list'
     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.

Modified: trunk/Catalyst-Plugin-PageCache/lib/Catalyst/Plugin/PageCache.pm
===================================================================
--- trunk/Catalyst-Plugin-PageCache/lib/Catalyst/Plugin/PageCache.pm	2008-10-01 10:25:02 UTC (rev 8492)
+++ trunk/Catalyst-Plugin-PageCache/lib/Catalyst/Plugin/PageCache.pm	2008-10-01 19:14:38 UTC (rev 8493)
@@ -108,17 +108,29 @@
 
     # Time to remove page from cache?
 
-    if ( $data->{expire_time} and $data->{expire_time} <= time ) {
-        $c->log->debug( "Expiring $key from page cache" )
-          if ($c->config->{'Plugin::PageCache'}->{debug});
+    if ( $data->{expire_time} && $data->{expire_time} <= time ) {
+        if ( my $busy_lock = $c->config->{'Plugin::PageCache'}->{busy_lock} ) {
+            # Extend the expiration time for others while
+            # this caller refreshes the cache
+            $data->{expire_time} = time() + $busy_lock;
+            
+            $c->cache->set( $key, $data );
+            
+            $c->log->debug( "$key has expired, being refreshed for $busy_lock seconds" )
+                if ($c->config->{'Plugin::PageCache'}->{debug});
+        }
+        else {
+            $c->log->debug( "Expiring $key from page cache" )
+              if ($c->config->{'Plugin::PageCache'}->{debug});
 
-        $c->cache->remove( $key );
+            $c->cache->remove( $key );
 
-        if ( !$c->config->{'Plugin::PageCache'}->{disable_index} ) {
-            my $index = $c->cache->get( "_page_cache_index" ) || {};
-            delete $index->{$key};
-            $c->cache->set( "_page_cache_index", $index,
-                $c->config->{'Plugin::PageCache'}->{no_expire});
+            if ( !$c->config->{'Plugin::PageCache'}->{disable_index} ) {
+                my $index = $c->cache->get( "_page_cache_index" ) || {};
+                delete $index->{$key};
+                $c->cache->set( "_page_cache_index", $index,
+                    $c->config->{'Plugin::PageCache'}->{no_expire});
+            }
         }
 
         return $c->NEXT::dispatch(@_);
@@ -322,6 +334,7 @@
     $c->config->{'Plugin::PageCache'}->{cache_headers}    ||= 0;
     $c->config->{'Plugin::PageCache'}->{set_http_headers} ||= 0;
     $c->config->{'Plugin::PageCache'}->{disable_index}    ||= 0;
+    $c->config->{'Plugin::PageCache'}->{busy_lock}        ||= 0;
     $c->config->{'Plugin::PageCache'}->{debug}            ||= $c->debug;
 
     # detect the cache plugin being used and set appropriate
@@ -482,7 +495,7 @@
 
 Enable this value if you need your cached responses to include custom HTTP
 headers set by your application.  This may be necessary if you operate behind
-an edge cache such as Akamai.
+an edge cache such as Akamai.  This option is disabled by default.
 
     set_http_headers => 1
 
@@ -490,7 +503,8 @@
 allow browsers and proxy servers to cache your page.  This will further reduce
 the load on your server.  The headers are set in such a way that the
 browser/proxy cache will expire at the same time as your cache.  The
-Last-Modified header will be preserved if you have already specified it.
+Last-Modified header will be preserved if you have already specified it.  This
+option is disabled by default.
 
     auto_cache => [
         $uri,
@@ -506,8 +520,20 @@
 In order to support the C<clear_cached_page> method, PageCache keeps an index of
 all cached pages.  If you don't intend to use C<clear_cached_page>, you may 
 enable this config option to avoid the overhead of creating and updating the
-cache index.
+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.  You will




More information about the Catalyst-commits mailing list