TooBasic: Cache
We All Know What It Is
True, we all know what a cache system is, the real question is what does TooBasic have to say about it?
What is it cached?
Internally, TooBasic separates the stuff it caches in two kinds:
- Computing Cache: This can also be called controller cache because it stores all the assignments made by a controller.
- View Cache: You can see this as a HTML cache where you store the final result of rendering a controller call.
Why is it separated? Well, if recall a cached controller but requesting a different format, you wouldn't want to run all your logics and queries and etc. when you only need a different format.
Adapters
From factory, TooBasic provides five basic types of cache adaptations you can choose on for your site and we are going to describe them.
File cache adapter
The most basic (and default) cache adapter provided by TooBasic is a class called \TooBasic\Adapters\Cache\File and it stores data inside files. When active, you'll find files coming and going inside ROOTDIR/cache/filecache.
Database cache adapter
A not very polite way of caching data is to store it inside a database, but in
some cases it could be useful (I hope Mr.Potato won't kill for suggesting this
mechanism).
For those cases, TooBasic provides an abstract adapter class called
\TooBasic\Adapters\Cache\DB and a specification for MySQL called
\TooBasic\Adapters\Cache\DBMySQL.
This adapter makes use of a table called cache (if there's a table prefix it
will use it) inside the database configured in
$Connections[GC_CONNECTIONS_DEFAULTS][GC_CONNECTIONS_DEFAULTS_CACHE] (or
$Connections[GC_CONNECTIONS_DEFAULTS][GC_CONNECTIONS_DEFAULTS_DB] if none) and
its structure will be created with a query like the next one (if MySQL):
create table if not exists cache (
cch_key varchar(256) collate utf8_bin not null,
cch_data blob not null,
cch_date timestamp not null default current_timestamp,
primary key(cch_key)
) engine=myisam default charset=utf8 collate=utf8_bin
By default, TooBasic will attempt to create this table every time it's
invoked, if you want to avoid this behavior you can set the global
$Defaults[GC_DEFAULTS_INSTALLED] to true.
Also
Also, TooBasic provides \TooBasic\Adapters\Cache\DBSQLite and \TooBasic\Adapters\Cache\DBPostgreSQL as cache on database adapters for SQLite and PostgreSQL.
Memcached adapter
A better approach is to use something like Memcached where you can store data in memory inside a cache service prepared for that task. For this, TooBasic provides a cache adapter class called \TooBasic\Adapters\Cache\Memcached and it requires settings like these:
<?php
$Defaults[GC_DEFAULTS_MEMCACHED][GC_DEFAULTS_MEMCACHED_SERVER] = 'localhost';
$Defaults[GC_DEFAULTS_MEMCACHED][GC_DEFAULTS_MEMCACHED_PORT] = 11211;
$Defaults[GC_DEFAULTS_MEMCACHED][GC_DEFAULTS_MEMCACHED_PREFIX] = '';
If you are wondering about
$Defaults[GC_DEFAULTS_MEMCACHED][GC_DEFAULTS_MEMCACHED_PREFIX], well when you
have more than one TooBasic based site using the same Memcached service,
you may find some collision problems and this global allows you to tag each cache
key with a prefix depending on your site.
Memcache adapter
If you are using memcache libraries (not memcached), try this:
<?php
$Defaults[GC_DEFAULTS_CACHE_ADAPTER] = '\\TooBasic\\Adapters\\Cache\\Memcache';
$Defaults[GC_DEFAULTS_MEMCACHE][GC_DEFAULTS_MEMCACHE_SERVER] = 'localhost';
$Defaults[GC_DEFAULTS_MEMCACHE][GC_DEFAULTS_MEMCACHE_PORT] = 11211;
$Defaults[GC_DEFAULTS_MEMCACHE][GC_DEFAULTS_MEMCACHE_PREFIX] = '';
Setting an adapter
We've been talking about cache adapter classes but we haven't said how to use them, well, that's the easy part, you just need to set something like the next piece of code and that's all:
<?php
$Defaults[GC_DEFAULTS_CACHE_ADAPTER] = '\\TooBasic\\Adapters\\Cache\\Memcached';
Cached controller
Now that you know all this about TooBasic's cache system, you need to know how to configure it for your controller. Once again, let's use a simple example, suppose we have a controller that displays a users' information... something like this:
<?php
class UserinfoController extends \TooBasic\Controller {
protected function basicRun() {
$user = $this->representations->users->item($this->params->get->userid);
$this->assign('info', $user->toArray());
$this->assign('bgcolor', isset($this->params->get->bgcolor) ? $this->params->get->bgcolor : 'red');
return $this->status();
}
protected function init() {
parent::init();
$this->_requiredParams['GET'][] = 'userid';
}
}
Now, let's say we want to cache this controller's calls based on the user ID and a parameter called bgcolor. For that we need to do two things:
- First, we need to activate the use of cache:
<?php class UserinfoController extends \TooBasic\Controller { protected $_cached = true; . . . } - And second we need to specify which parameters to take in consideration when
generating a cache key:
<?php class UserinfoController extends \TooBasic\Controller { . . . protected function init() { . . . $this->_cacheParams['GET'][] = 'userid'; $this->_cacheParams['GET'][] = 'bgcolor'; . . . } }
All together will look like this:
<?php
class UserinfoController extends \TooBasic\Controller {
protected $_cached = true;
protected function basicRun() {
$user = $this->representations->users->item($this->params->get->userid);
$this->assign('info', $user->toArray());
$this->assign('bgcolor', isset($this->params->get->bgcolor) ? $this->params->get->bgcolor : 'red');
return $this->status();
}
protected function init() {
parent::init();
$this->_cacheParams['GET'][] = 'userid';
$this->_cacheParams['GET'][] = 'bgcolor';
$this->_requiredParams['GET'][] = 'userid';
}
}
And that's it, from now on, our controller saves cache entries and calls like these will have different entries:
- http://www.example.com/?action=userinfo&userid=10&bgcolor=green
- http://www.example.com/?action=userinfo&userid=10&bgcolor=blue
- http://www.example.com/?action=userinfo&userid=12&bgcolor=green
- http://www.example.com/?action=userinfo&userid=10
What about the last one? well, if you don't pass a parameter called bgcolor it will consider it as empty and generate a different key.
Cached services?
Yes, services can also be cached in the same way a controller does.
What if you don't want it?
Yes, what if you don't want any cache system and the use of &debugresetcache in
the url annoys you?
Well, there's an adapter called \TooBasic\Adapters\Cache\NoCache that acts as
a dummy providing you with the solution.
It will interact as any other cache adapter but it won't do a thing and you'll
be working without cache.
Duration
Before version 0.3.0, every cache entry had a duration of 3600 seconds (one hour) and it couldn't be changed, but now it is possible adding something like this in your site's configuration file:
<?php
$Defaults[GC_DEFAULTS_CACHE_EXPIRATION] = 86400; // 1 day
You can also change your controllers and use something like this:
<?php
class MyactionController extends \TooBasic\Controller {
protected $_cached = \TooBasic\Adapters\Cache\Adapter::EXPIRATION_SIZE_LARGE;
public function basicRun() {
. . .
This constant will tell TooBasic to use an expiration time as long as it's configured.
Available constants are:
\TooBasic\Adapters\Cache\Adapter::EXPIRATION_SIZE_DOUBLE: Double of$Defaults[GC_DEFAULTS_CACHE_EXPIRATION].\TooBasic\Adapters\Cache\Adapter::EXPIRATION_SIZE_LARGE: Same size as$Defaults[GC_DEFAULTS_CACHE_EXPIRATION].\TooBasic\Adapters\Cache\Adapter::EXPIRATION_SIZE_MEDIUM: A half of$Defaults[GC_DEFAULTS_CACHE_EXPIRATION].\TooBasic\Adapters\Cache\Adapter::EXPIRATION_SIZE_SMALL: A quarter of$Defaults[GC_DEFAULTS_CACHE_EXPIRATION].
Any other value will be considered as
\TooBasic\Adapters\Cache\Adapter::EXPIRATION_SIZE_LARGE, including the boolean true used
in versions before 0.3.0.