[14]JCache Implementation

Locked
User avatar
ircmaxell
Joomla! Ace
Joomla! Ace
Posts: 1926
Joined: Thu Nov 10, 2005 3:10 am
Location: New Jersey, USA
Contact:

[14]JCache Implementation

Post by ircmaxell » Wed Feb 20, 2008 7:57 pm

1. Introduction

1.1 Scope
The scope of this document is a first draft of improvements to the JCache class introduced in Joomla! 1.5.

1.2 Objective of the document
The objective is to give a basis for a discussion about an extension/refactor of the JCache class for Joomla! 1.6.

1.3 General remarks
This proposal is based on the functionality of JCache in the Joomla! 1.5 stable versions.

1.4 Definitions
  • Cache - Server side storage of data
  • Storage Handler - Actual method of storing cache data
  • Cache Handler - Class that abstracts caching layer (ex: callback caching)
  • Cache Helper - Class that works between cache handler and caller (ex: module caching)
  • Cache Hit – Data is stored in the cache, and is returned
  • Cache Miss – Data is not stored in the cache, and the lookup fails
  • Primed Cache – Common used data exists in the cache.
1.5 License
GNU GPL

2. What is the current functionality of JCache

2.1 Design
JCache currently can be broken down into two parts, the cache handler and the storage handler. This allows JCache to function independent of the type of cache handler or storage handler used.

2.2 Methodology
JCache currently checks cached items for validity (including time to live calculations, and whether to cache an item or no) on fetch. This involves loading parameters for the item prior to fetching the item from the cache (if it exists).

3. What are the proposed improvements?

3.1 Addition Of JCacheHelper Classes
JCacheHelper classes will abstract cache related solutions unique to different areas of the core. One example of this occurs with modules. Some modules never change output on the entire site, whereas others change depending on the page. JCacheHelperModule would generate 2 cache ids for each module (one for the current page, and one that's site wide. This would allow caching of modules and module positions if the modules do not change.

3.2 Addition of Additional Cache Handler Classes

3.2.1 JCacheRaw
JCacheRaw will provide direct access to the cache so an extension can send raw data to the cache. This would allow an extension to handle the id and data generation on its side for abstract use. This would be useful in such areas as JRegistry to cache internal variable data.

3.2.2 JCacheObject
JCacheObject will provide storage for instances of objects. The variables passed to the handler would be class name, and any constructor arguments. This will allow the caching of objects such as JUser, JLanguage, and JACL.

3.2.3 JCacheQuery
JCacheQuery will provide a mechanism to cache the results from queries. As parameters, it would accept the query string, the expected result set as a string (the function to call in the JDatabase object), and the known lifetime if it exists (for queries dependant on publish times, this would be stuck to around 60 seconds). The handler would check the cache to see if the result exists. If it does not, it executes the query and stores the result.

3.3 Change of JCache Methodology

3.3.1 Validation
Validation will occur when data is stored in JCache. This includes any time to live or enabled calculations. This is because a cache request is significantly faster than the time it takes to build the parameters needed to determine cachability. The tradeoff is that every load results in a check to the cache regardless of if the item is cacheable. However, a cache hit will be significantly faster than the current validation check.

3.3.2 Extending Validation
Validation will be able to be extended by the individual extensions (in the case of view and page handlers). This allows for disabling caching (or adjusting TTL) of items before they go into the cache. This will be realized by attaching a callback to the cache class. When JCache validates data (before storing it), it will call the callback and adjust the validation results before storing the data.

4. Technical Realization

4.1 Core Changes
Every place in the core that has data that could be cached would need to be altered to use the new system.

4.2 Global Parameter Additions
New global parameters would need to be added that would disable or alter the TTL for their respective cache items (For example, to disable page caching for a specific menu item).

4.3 Module Parameter Additions
New Module parameter (or xml definition) would be added which would define whether the module changes depending on the page or not (such as a menu module changing the active menu item versus a newest content module).

5. Intention
The current framework for Joomla 1.5 and 1.6, while being quite powerful and flexible, can be significantly slower than past and competing technologies. The core needs aggressive caching with a robust system which will compensate for the added weight of the framework.

6. Effects on...

6.1 Users
Proper implementation should have no negative effect on users

6.2 3P extensions
While these changes should have no negative effect on extensions, they should allow for an easier to use, and more flexible cache system.

6.3 Performance

6.3.1 Cache Disabled Globally
There should be no effect on performance when the global cache is disabled

6.3.2 Global Cache Enabled, Not Primed
A request for an item which is not in the cache should be no slower than the current implementation (since the same steps are taken, just in a different order).

6.3.3 Global Cache Enabled, Primed
A request for an item which is in the cache should be significantly faster than the current implementation due to the elimination of loading the parameters and checking the validity of that item.

6.3.4 Global Cache Enabled, Local Cache Disabled
When caching is disabled for specific items (such as a module), it will be a little bit slower than the current implementation due to the additional check for cache data (the cache is still checked, but never stored for a disabled item).

6.4 System Requirements
Due to the fact that aggressive caching can significantly lower the respective load on a server, a physical server should be able to serve significantly more requests with the proposed improvements.
Anthony Ferrara - Core Team - Development Coordinator - Bug Squad - JSST

http://moovum.com/ - The Bird is in the air! Get Mollom Anti-Spam on your Joomla! website with Moovur...
http://www.joomlaperformance.com For All Your Joomla Performance Needs

Nils
Joomla! Apprentice
Joomla! Apprentice
Posts: 7
Joined: Sun Sep 10, 2006 8:05 pm

Re: JCache Implementation

Post by Nils » Tue Mar 04, 2008 9:20 pm

:-\ Please delete this post if it is just plain stupid I guess I am just a noob compared to the original poster...

I fully agree to this whitepaper. I have been using Cache_Lite with a module (LiveUsersPro) and intent on using caching to greater extend in future extensions.

PRO this whitepaper: Cache_lite doesn't seem to be included anymore and my first attempts using JCache directly failed (cache doesn't expire)

Code: Select all

$cache = new JCache(options)... $cache->setLifetime... $cache->store.. $cache->get.... 
I don't want to whine about that, maybe I am just to dumb to figure out how to use it correctly, but if JCache is not to be used directly then the additions mentioned in this whitepaper could be useful.

CONTRA this whitepaper: Maybe the callback method can be used on all the cases presented in the whitepaper as it caches the output of a function.

Code: Select all

$cache =& JFactory::getCache('myExtensionCache);
			$cachedOutput = $cache->call(array('myFunction'), $myFunctionParams);
			echo $cachedOutput
Moving the data that would require caching to a separate function may solve many of those cases. As far as I understand JProfiler helps determining if caching that particular function makes sense.

Hope comments on whitepapers are ok ???

User avatar
ircmaxell
Joomla! Ace
Joomla! Ace
Posts: 1926
Joined: Thu Nov 10, 2005 3:10 am
Location: New Jersey, USA
Contact:

Re: JCache Implementation

Post by ircmaxell » Tue Mar 04, 2008 9:40 pm

Nils wrote::-\ Please delete this post if it is just plain stupid I guess I am just a noob compared to the original poster...
The only stupid reply, is one that hasn't been thought out, yours obviously has
I fully agree to this whitepaper. I have been using Cache_Lite with a module (LiveUsersPro) and intent on using caching to greater extend in future extensions.

PRO this whitepaper: Cache_lite doesn't seem to be included anymore and my first attempts using JCache directly failed (cache doesn't expire)

Code: Select all

$cache = new JCache(options)... $cache->setLifetime... $cache->store.. $cache->get.... 
I don't want to whine about that, maybe I am just to dumb to figure out how to use it correctly, but if JCache is not to be used directly then the additions mentioned in this whitepaper could be useful.
Well, there are some methods available to you now that you should be able to use (such as callback)... Also, use $cache =& JFactory::getCache();
CONTRA this whitepaper: Maybe the callback method can be used on all the cases presented in the whitepaper as it caches the output of a function.

Code: Select all

$cache =& JFactory::getCache('myExtensionCache);
			$cachedOutput = $cache->call(array('myFunction'), $myFunctionParams);
			echo $cachedOutput
Moving the data that would require caching to a separate function may solve many of those cases. As far as I understand JProfiler helps determining if caching that particular function makes sense.

Hope comments on whitepapers are ok ???
This works for caching output. But what about results? (Like, say, parsing INI data). Flexability is key...
Anthony Ferrara - Core Team - Development Coordinator - Bug Squad - JSST

http://moovum.com/ - The Bird is in the air! Get Mollom Anti-Spam on your Joomla! website with Moovur...
http://www.joomlaperformance.com For All Your Joomla Performance Needs

User avatar
Dionisiy
Joomla! Intern
Joomla! Intern
Posts: 98
Joined: Thu Mar 16, 2006 11:00 am
Location: Minsk, Belarus
Contact:

More individual cache controls

Post by Dionisiy » Wed Mar 19, 2008 11:18 am

We need more control over the cache - i.e. use different cache time for different cache groups.
As JFactory::getCache() is the most common way to setup the cache and can be used in custom display of the controller (replacement of the standard controller's 'display' function) I propose to enchance it with cache option:

current function in JFactory class:

Code: Select all

function &getCache($group = '', $handler = 'callback', $storage = null)
new versionL

Code: Select all

function &getCache($group = '', $handler = 'callback', $storage = null, $options = null, $caching = null)
if $options and $caching are setup as function parameters - the function should use it, otherwise the default should be used as in current version:
$options = array(
'defaultgroup' => $group,
'cachebase' => $conf->getValue('config.cache_path'),
'lifetime' => $conf->getValue('config.cachetime') * 60, // minutes to seconds
'language' => $conf->getValue('config.language'),
'storage' => $storage
);
...
$cache->setCaching($conf->getValue('config.caching'));
So the new function will be (full solution):

Code: Select all

	function &getCache($group = '', $handler = 'callback', $storage = null, $options = null, $caching = null)
	{
		$handler = ($handler == 'function') ? 'callback' : $handler;

		$conf =& JFactory::getConfig();

		if(!isset($storage)) {
			$storage = $conf->getValue('config.cache_handler', 'file');
		}

		if(!isset($options)) {
			$options = array(
				'defaultgroup' 	=> $group,
				'cachebase' 	=> $conf->getValue('config.cache_path'),
				'lifetime' 		=> $conf->getValue('config.cachetime') * 60,	// minutes to seconds
				'language' 		=> $conf->getValue('config.language'),
				'storage'		=> $storage
			);
		}
		else {
			if(!isset($options['defaultgroup'])) {
				$options['defaultgroup'] = $group;
			}
			if(!isset($options['cachebase'])) {
				$options['cachebase'] = $conf->getValue('config.cache_path');
			}
			if(!isset($options['lifetime'])) {
				$options['lifetime'] = $conf->getValue('config.cachetime') * 60;
			}
			if(!isset($options['language'])) {
				$options['language'] = $conf->getValue('config.language');
			}
			if(!isset($options['storage'])) {
				$options['storage'] = $storage;
			}
		}
		
		if(!isset($caching)) {
			$caching = $conf->getValue('config.caching');
		}

		jimport('joomla.cache.cache');

		$cache =& JCache::getInstance( $handler, $options );
		$cache->setCaching($caching);
		return $cache;
	}
$storage function parameter can be removed (but this will break compatibility and require small function changing).

This will allow custom cache settings for each custom component, i.e. we can have different cache time for each component, and cache/don't cache it no matter if global caching is off/on.

3 caching options for the modules are also required(don't remember - may be already posted this request):
1. Use global
2. Caching
3. No caching

The 2nd and 3rd options should be applied no matter if global caching is allowed or not.

User avatar
ircmaxell
Joomla! Ace
Joomla! Ace
Posts: 1926
Joined: Thu Nov 10, 2005 3:10 am
Location: New Jersey, USA
Contact:

Re: [14]JCache Implementation

Post by ircmaxell » Mon Mar 24, 2008 10:43 pm

The only problem with that, is it forces you to find out data about what you are caching before trying to see if it's in cache. (Basically, it goes against the "validate on store" principal I try to stick to). I did plan on making the TTL available on store, so you can change it when you store the cache.

The validate on store principal is basically to determine the least about the object as possible before checking the cache. To see why this is effective, lets look at modules. Let's say you can cache the entire left position. In order to fetch the data, all you need to know is the name of the position "left", and the Itemid (identifying the page). Now, in the current setup, you'd have to determine each module's name, and load the params to see if each one is cachable BEFORE doing a cache fetch. Validate On Store basically assumes that a read is much cheaper than building params, which implies that if the object exists in cache, then it must have been cachable!
Anthony Ferrara - Core Team - Development Coordinator - Bug Squad - JSST

http://moovum.com/ - The Bird is in the air! Get Mollom Anti-Spam on your Joomla! website with Moovur...
http://www.joomlaperformance.com For All Your Joomla Performance Needs

User avatar
torkil
Joomla! Guru
Joomla! Guru
Posts: 726
Joined: Wed Aug 24, 2005 9:34 am
Location: Rørvik, Norway
Contact:

Re: [14]JCache Implementation

Post by torkil » Fri May 23, 2008 7:17 am

Ideally I'd like to be able to specify different cache times for different parts of my component too. For instance my model might be fetching data that rarely changes or gets updated, like a list of countries, currencies or similar, but on the other hand also be fetching data that updates often, like a list of comments or something like that.

User avatar
Dionisiy
Joomla! Intern
Joomla! Intern
Posts: 98
Joined: Thu Mar 16, 2006 11:00 am
Location: Minsk, Belarus
Contact:

Re: [14]JCache Implementation

Post by Dionisiy » Fri May 23, 2008 8:21 am

This can be easily achieved if the getCache() function will be enlarged with the options as I've described before, you will be able to do it like this:

Code: Select all

$cache =& JFactory::getCache($option.'_'.$view_name, 'view', null, $options);
$cache->get($view, 'display');
$options can be setup to use different cache times for the different views, and using $option.'_'.$view_name you can use different cache group for each view

User avatar
ircmaxell
Joomla! Ace
Joomla! Ace
Posts: 1926
Joined: Thu Nov 10, 2005 3:10 am
Location: New Jersey, USA
Contact:

Re: [14]JCache Implementation

Post by ircmaxell » Fri May 23, 2008 5:39 pm

torkil wrote:Ideally I'd like to be able to specify different cache times for different parts of my component too. For instance my model might be fetching data that rarely changes or gets updated, like a list of countries, currencies or similar, but on the other hand also be fetching data that updates often, like a list of comments or something like that.
You can do that already

Code: Select all

$cache =&JFactory::getCache(whatever);
$cache->setTimeLimit((int) $myNewTimelimit);
There is a bug (I just found it thursday) that causes it not to respect this new time, but I'm working to fix that for 1.5.4...

for a status on this:
http://developer.joomla.org/developer-t ... nd-16.html
Anthony Ferrara - Core Team - Development Coordinator - Bug Squad - JSST

http://moovum.com/ - The Bird is in the air! Get Mollom Anti-Spam on your Joomla! website with Moovur...
http://www.joomlaperformance.com For All Your Joomla Performance Needs

mkhedri
Joomla! Fledgling
Joomla! Fledgling
Posts: 1
Joined: Wed Oct 14, 2009 2:09 pm

Re: [14]JCache Implementation

Post by mkhedri » Wed Oct 14, 2009 2:31 pm

Hi,

I have been looking around to find a good solution/plugin that enables me to delete a specific cache item instead of removing the whole cached group from Cache Manager.
e.g.
Each time a new content is added/updated, I would like to be able to ONLY remove the cached index and the cached content.

It is pretty anoying to remove the whole content and page cache when adding/updating a content.

I would appreciate if you had a solution for this the could help me.

Thank you in advance
M

User avatar
torkil
Joomla! Guru
Joomla! Guru
Posts: 726
Joined: Wed Aug 24, 2005 9:34 am
Location: Rørvik, Norway
Contact:

Re: [14]JCache Implementation

Post by torkil » Wed Oct 14, 2009 6:20 pm

Interesting problem. Clearing the entire com_content cache every time one article is updated is really unneccessary, but this is what the Joomla core does.

When implementing this in your own code, you can forge your own destiny of course, let me try to explain:

You call JCache::remove() basically. The method takes two arguements: Id and group. Id is the id of the item you want to delete, and group is the group the item is in. For instance if you want to delete a cached item from com_content, the group is "com_content". Group equals the name of the folder that resides inside /cache, and that holds your cached item.

So what you really need to find out, is: What is the id of the item I want to delete? Well, this is all in the hands of the people who created the component actually. A cached view of an article with database id 15 could have cache id as easy as just "article15" or "art-15", there is really no way of telling unless you look up the code that generates the id when the items are cached.

If you look at for instance com_content and the caching of articles, it is done in the component controller which calls JController::display(true), where true means that the item is cacheable. the display() method in turn calls $cache->get(), and this is where the id is provided. It consists of a view object where possibly also a model is set and a viewlayout too it seems. So not that straight forward to reproduce, but not impossible by all means.

User avatar
joomfriend
Joomla! Explorer
Joomla! Explorer
Posts: 284
Joined: Sun Feb 08, 2009 5:10 pm
Contact:

Re: [14]JCache Implementation

Post by joomfriend » Mon Dec 14, 2009 3:46 am

Same as mkhedri, I have been looking for the same solution.

Also, I would like to be able the enable the Global cache system while being able to disable a cache for a specific module like: 3rd party Ads/banner module, Online user/article stats etc. Any solution?

There is another BIG PROBLEM with the main Joomla caching system: Cache and Hits can't work together. Since I enable my Global cache, Article Hit counter stopped working. I couldn't be able to find a solution for that issue. Any fix/solution shall be highly appreciated.
- https://www.adelnipet.com: Adelni Pet - Your Social Pet Network
- https://www.egliseprimitive.org: Christian Website


Locked

Return to “Under Review - Archived”