One of the many changes in the feedstock alpha 3 is the new way caching works. Before there were two different types of caching, static and dynamic. Each of those needed their own classes to communicate with the backends, Ex. ApcDynamic and ApcStatic. There are still static and dynamic options but they don't need separate classes to run. The static option stores the final output of a page so when it is called again it just loads the final output and sends it to the client. The dynamic option caches sql queries and their results, this way pages are still generated on each page load.
I was able to get rid of two separate cache backends by creating an interface called GenericCacher and creating a CacherCreator class. The GenericCacher interface defines functions that each cacher must have. The CacherCreator class checks to see if the currently loaded cacher is an instance of the GenericCacher interface. If it is an instance of GenericCacher then we know it is going to implement all of the functions in GenericCacher. By requiring each cacher implement GenericCacher I was able to structure my code so both forms of caching, static and dynamic, are supported by the same cacher class.
Now FileCache supports both static and dynamic caching, where it previously only supported static caching. This means that if a host doesn't support anything like APC or Xcache someone could cache either sql or fully generated pages on disk. I ended up having FileCache serialize and unserialize data when writing and reading files from disk. The nice thing with serialize is I can store arrays in files and read them back into an array with the same format, definitely comes in handy when the sql results are going to be arrays. Using FileCache is usually slower than using APC or Xcache (This is because those caching backends store data in memory) but it is usually faster than running without any caching.
One of the nice things about rewriting the way caching works is that it is now really easy to add support for new caching methods. One of the caching methods feedstock currently does not support is Memcached. The main reason for this is that I don't have a Memcached server to test things on. If I were to support Memcached it wouldn't be hard to get it added to feedstock. All I would need to do is add a Memcached.php file (and a Memcached class inside of that) that implements GenericCacher. Once there I would just need to set up the logic and then change $this->config['cacheName'] = 'something' to = 'Memcached' . There will probably need to be some changes to the way caching classes work because Memcached would need to take in a list servers it can connect to.
Something I might add to GenericCacher is allowing the constructor take in an optional array of options at the end. This would allow future caching methods (like Memcached) to take in custom options. These custom options could be a list of servers to connect to.
To sum things up the way caching is implemented in feedstock alpha 3 is greatly improved over previous versions. It is now easier to support new caching methods, easier to make changes to the way caching methods work (via things like GenericCacher interface), and easier to support the two (static/dynamic) types of caching data.
I was able to get rid of two separate cache backends by creating an interface called GenericCacher and creating a CacherCreator class. The GenericCacher interface defines functions that each cacher must have. The CacherCreator class checks to see if the currently loaded cacher is an instance of the GenericCacher interface. If it is an instance of GenericCacher then we know it is going to implement all of the functions in GenericCacher. By requiring each cacher implement GenericCacher I was able to structure my code so both forms of caching, static and dynamic, are supported by the same cacher class.
Now FileCache supports both static and dynamic caching, where it previously only supported static caching. This means that if a host doesn't support anything like APC or Xcache someone could cache either sql or fully generated pages on disk. I ended up having FileCache serialize and unserialize data when writing and reading files from disk. The nice thing with serialize is I can store arrays in files and read them back into an array with the same format, definitely comes in handy when the sql results are going to be arrays. Using FileCache is usually slower than using APC or Xcache (This is because those caching backends store data in memory) but it is usually faster than running without any caching.
One of the nice things about rewriting the way caching works is that it is now really easy to add support for new caching methods. One of the caching methods feedstock currently does not support is Memcached. The main reason for this is that I don't have a Memcached server to test things on. If I were to support Memcached it wouldn't be hard to get it added to feedstock. All I would need to do is add a Memcached.php file (and a Memcached class inside of that) that implements GenericCacher. Once there I would just need to set up the logic and then change $this->config['cacheName'] = 'something' to = 'Memcached' . There will probably need to be some changes to the way caching classes work because Memcached would need to take in a list servers it can connect to.
Something I might add to GenericCacher is allowing the constructor take in an optional array of options at the end. This would allow future caching methods (like Memcached) to take in custom options. These custom options could be a list of servers to connect to.
To sum things up the way caching is implemented in feedstock alpha 3 is greatly improved over previous versions. It is now easier to support new caching methods, easier to make changes to the way caching methods work (via things like GenericCacher interface), and easier to support the two (static/dynamic) types of caching data.
Categories: projects
Date: 04/14/11
In my post yesterday I mentioned that I was managing what data I had written to xcache in my xcacheDynamic class because if a post is added while there are cached values we need to clear those values so users can see the new post right away.
In the xcacheStatic class I tried to use xcache_unset_by_prefix() but I assume that is a xcache 1.3 feature as in 1.2.2, which I currently run, it caused a function not defined error. This definitely makes things harder as I attach a prefix to every entry in xcache so deleting using this function makes things trivial.
This is what I did in the xcacheStatic and xcacheDynamic classes, I used an associative array. So essentially what that means is if the prefix is test_ then in the cache there is a test_array entry that stores an associative array containing all the items I have added to the cache. Why an associative array? I can set the key to the hash of the query and the value to the hash of the query. Then it is stored inside the var cache. This makes it easy to see if the value already exists in the array using isset(), thus if it exists I don't need to push something else onto the array. It's also nice because when we purge the cache I am able to iterate through the array and each value is the hash i need to delete. The nice thing in PHP is you can iterate through associative arrays.
The only reason I need this is if an update/insert/delete happens to something in the database and the cache hasn't been garbage collected yet. This way theres no waiting for the cache to expire in order to show new data, it is shown after the data is inserted in the database. Now I wouldn't need to use the array method if I were able to delete by prefix, but thats okay as this method works fine.
Oh and I only need to update the array when something is being written to the var cache.
the pseudocode is something like
if(don't have the array in xcache)
{
create an array containing the hash as the key and as the value.
write that as something like prefix_somethingweknow into xcache
}
else
{
grab the array from xcache
check if it contains this value
if it doesn't then add it and write the entire thing to xcache
}
In the xcacheStatic class I tried to use xcache_unset_by_prefix() but I assume that is a xcache 1.3 feature as in 1.2.2, which I currently run, it caused a function not defined error. This definitely makes things harder as I attach a prefix to every entry in xcache so deleting using this function makes things trivial.
This is what I did in the xcacheStatic and xcacheDynamic classes, I used an associative array. So essentially what that means is if the prefix is test_ then in the cache there is a test_array entry that stores an associative array containing all the items I have added to the cache. Why an associative array? I can set the key to the hash of the query and the value to the hash of the query. Then it is stored inside the var cache. This makes it easy to see if the value already exists in the array using isset(), thus if it exists I don't need to push something else onto the array. It's also nice because when we purge the cache I am able to iterate through the array and each value is the hash i need to delete. The nice thing in PHP is you can iterate through associative arrays.
The only reason I need this is if an update/insert/delete happens to something in the database and the cache hasn't been garbage collected yet. This way theres no waiting for the cache to expire in order to show new data, it is shown after the data is inserted in the database. Now I wouldn't need to use the array method if I were able to delete by prefix, but thats okay as this method works fine.
Oh and I only need to update the array when something is being written to the var cache.
the pseudocode is something like
if(don't have the array in xcache)
{
create an array containing the hash as the key and as the value.
write that as something like prefix_somethingweknow into xcache
}
else
{
grab the array from xcache
check if it contains this value
if it doesn't then add it and write the entire thing to xcache
}
Categories: projects
Date: 04/29/10