dumbCache, or, I /have/ been working on code?!

It’s rare (never) that I blog about code, little alone blog anything. Today is not one of those days. I should have known it would be a special/different day when I woke up with ELO’s “Hold on tight to your dreams” stuck in my head.

One of my most recent project I have inherited is (regretfully) based half in phpCake, half in homerolled calls to mysql_query(). It makes for rather strange bedfellows.

This system partially utilized cake’s native Cache::Write/Cache::Read functions, but it only had primitive support, it was only compatible with cake’s engine type of ‘File’, which is rarely what you truly want.

I began implementing a single-host compatbile memcache which worked with PHPCake’s memcache daemon, but I really wanted it to be able to fail-through gracefully, rather than fall flat upon it’s face. I did some searching, and ran into SuperStack.

SuperStack is a simplistic attempt at doing precisely what I was looking for – with the added benefit of arbitrating cake’s own cache engines, so, he could get a list, call the functions, and be done with it – adding support for writing through to caches that are missing the data.

I took about 5 minutes (ok, about 2, it’s small) to read the code, and immediately made it part of the system, replacing the default Engine in cake. Now, I had both memcache, and a local file cache – just in case.

I wanted dumbCache to be able to support virtually every configuration available to cake, with minimal config differences. I wrote a wrapper to init() the Memcache servers given, rewrote the File support, and finally, added Redis. Then, I added basic error checking for testing upon init, and disabling them after the initial call, so no waste would take place on any subsequent read/writes after the init.

Here’s what the (ugly) config looks like:

$config = array(
        'Memcache' => array(
                'enabled' => TRUE,
                'host' => array(
                        "127.0.0.1:11211",
                        "127.0.0.1:11212",
                ),
        ),
        'Redis' => array(
                'enabled' => TRUE,
                'host' => array(
                        "127.0.0.1:6379",
                ),
        ),
        'File' => array(
                'enabled' => TRUE,
                'directory' => '../tmp/cache/',
        ),
);

As this is a simple write-through cache, it will attempt to populate all engines, and if it finds one missing a value, will attempt to write it, just to have it. Thanks, Richard, for the inspiration.

dumbCache weighs in at an amazing 7.2k, and has the following functions (to be compatible with the existing software):

cacheInit(), cacheRead(), cacheWrite(), and cacheDelete().

It prefers owlient’s phpredis (as that supports setTimeout so you can automatically expire data as with Memcache and the File subsystem), and was written for Memcache as is distributed via pecl.

[Update: Dec 15th, 2010:]

adam@adam.gs gets props for answering 20 questions related to his caching methods, none of which were actually applicable, or useful.