Source for file _blockcache.class.php
Documentation is available at _blockcache.class.php
* This file implements the BlockCache class, which caches HTML blocks/snippets genereated by the app.
* This file is part of the evoCore framework - {@link http://evocore.net/}
* See also {@link http://sourceforge.net/projects/evocms/}.
* @copyright (c)2003-2010 by Francois PLANQUE - {@link http://fplanque.net/}
* Parts of this file are copyright (c)2004-2006 by Daniel HAHLER - {@link http://thequod.de/contact}.
* {@internal License choice
* - If you have received this file as part of a package, please find the license.txt file in
* the same folder or the closest folder above for complete license terms.
* - If you have received this file individually (e-g: from http://evocms.cvs.sourceforge.net/)
* then you must choose one of the following licenses before using the file:
* - GNU General Public License 2 (GPL) - http://www.opensource.org/licenses/gpl-license.php
* - Mozilla Public License 1.1 (MPL) - http://www.opensource.org/licenses/mozilla1.1.php
* {@internal Open Source relicensing agreement:
* @version $Id: _blockcache.class.php,v 1.11 2010/02/08 17:51:42 efy-yury Exp $ }}}
if( !defined('EVO_MAIN_INIT') ) die( 'Please, do not access this page directly.' );
* After how many bytes should we output sth live while collecting cache content:
* Progressively caching the content of the current page:
* Are we currently recording cache contents
// Make sure keys are always in the same order:
foreach( $keys as $key =>
$val )
// echo $this->serialized_keys;
* Invalidate a special key
* All we do is store the timestamp of teh invalidation
$lastchanged_key_name =
'last_changed+'.
$key.
'='.
$val;
// Invalidate using the real time (seconds may have elapsed since $sertimenow)
// Add 1 second because of teh granularity that's down to teh second
// Worst case scenario: content will be collected/cahced several times for a whole second (as well as the first request after the end of that second)
$Debuglog->add( 'Invalidated: '.
$lastchanged_key_name.
' @ '.
(time()+
1), 'blockcache' );
* Check if cache contents are available, otherwise start collecting output to be cached
* Basically we get all the invalidation dates we need, then we get the
* data and then we check if some invalidation occured after the data was cached.
* If an invalidation date is missing we consider the cache to be
* obsolete but we generate a new invalidation date for next time we try to retrieve.
* @return true if we found and have echoed content from the cache
$most_recent_invalidation_ts =
0;
$most_recent_invaliating_key =
'';
foreach( $this->keys as $key =>
$val )
$lastchanged_key_name =
'last_changed+'.
$key.
'='.
$val;
{ // We have lost the key! Recreate and keep going for other keys:
$Debuglog->add( 'Missing: '.
$lastchanged_key_name, 'blockcache' );
if( $last_changed_ts >
$most_recent_invalidation_ts )
{ // This is the new most recent invalidation date.
$most_recent_invalidation_ts =
$last_changed_ts;
$most_recent_invaliating_key =
$lastchanged_key_name;
if( !$missing_date &&
$this->retrieve( $most_recent_invalidation_ts, $most_recent_invaliating_key ) )
{ // cache was not invalidated yet and we could retrieve:
* Retrieve and output cache
* @param integer oldest acceptable timestamp
* @return boolean true if we could retrieve
function retrieve( $oldest_acceptable_ts =
NULL, $most_recent_invaliating_key =
'' )
if( !is_null($oldest_acceptable_ts) )
{ // We want to do timestamp checking:
//if( ! preg_match( '/^([0-9]+) (.*)$/ms', $content, $matches ) )
if( ! $pos =
strpos( $content, ' ' ) )
{ // Could not find timestamp
$Debuglog->add( 'MISSING TIMESTAMP on retrieval of: '.
$this->serialized_keys, 'blockcache' );
// if( $matches[1] < $oldest_acceptable_ts )
if( ($cache_ts =
substr( $content, 0, $pos )) <
$oldest_acceptable_ts )
{ // Timestamp too old (there has been an invalidation in between)
$Debuglog->add( 'Retrieved INVALIDATED cached content: '.
$this->serialized_keys
.
' (invalidated by '.
$most_recent_invaliating_key.
' - '.
$cache_ts.
' < '.
$oldest_acceptable_ts.
')', 'blockcache' );
// OK, we have content that is still valid:
// $content = $matches[2];
$content =
substr( $content, $pos+
1 );
* This is called every x bytes to provide real time output
* We are going to output personal data and we want to abort collecting the data for the cache.
{ // We are not collecting anyway
$Debuglog->add( 'Aborting cache data collection...', 'blockcache' );
// We are no longer collecting...
* End collecting output to be cached
* We just concatenate all the individual keys to have a single one
* Then we store with the current timestamp
{ // We are not collecting
// We use servertimenow because we may have used data that was loaded at the very start of this page
* put your comment there...
* @todo dh> This method should get removed from here, it's not limited to BlockCache.
$ttl =
3600 *
24; // TODO: dh> should become a param to the method?!
return apc_store( $key, $payload, $ttl );
return eaccelerator_put( $key, $data, $ttl );
* put your comment there...
* @todo dh> This method should get removed from here, it's not limited to BlockCache.
return apc_fetch( $key, $success );
$r =
eaccelerator_get($key);
* $Log: _blockcache.class.php,v $
* Revision 1.11 2010/02/08 17:51:42 efy-yury
* Revision 1.10 2009/12/22 08:02:12 fplanque
* Revision 1.9 2009/12/22 03:43:10 blueyed
* Revision 1.8 2009/12/22 02:56:35 blueyed
* BlockCache: add support for xcache and eaccelerator
* Revision 1.7 2009/12/06 03:24:11 fplanque
* Revision 1.6 2009/12/01 04:19:25 fplanque
* even more invalidation dimensions
* Revision 1.5 2009/12/01 03:33:19 fplanque
* Improved handling of invalidation dates
* Revision 1.4 2009/12/01 02:04:45 fplanque
* Revision 1.3 2009/12/01 01:33:21 blueyed
* Fix install: wrap apc_*
* Revision 1.2 2009/11/30 23:16:24 fplanque
* basic cache invalidation is working now
* Revision 1.1 2009/11/30 04:31:37 fplanque
* BlockCache Proof Of Concept