CacheManager

Wie der Roadmap zu entnehmen ist, beinhaltet die Version 1.8 das Redesign des Cache-Managers. Nachteil der bisherigen Implementierung war die starre Handhabung der jeweiligen Cache-Klassen und die suboptimale Möglichkeit der Erweiterung derselben.

Der neu implementierte CacheManager ist daher einfach gehalten, bietet jedoch eine sehr einfache und zugleich mächtige Möglichkeit, diesen zu erweitern. Der CacheManager selbst kümmert sich dabei nur um die Verwaltung und Initialisierung der CacheProvider, die sich letztlich um die Funktion des Lesens, Schreibens und Löschen von Cache-Inhalten kümmern. Im Release sind bereits wichtige Provider und eine abstrakte Definition zur Implementierung von eigenen Providern enthalten.


1. Konfiguration

Der CacheManager erwartet eine Konfigurationsdatei im Namespace tools::cache, dem aktuellen Context und dem Namen cacheconfig. Für die Verwendung des CacheManagers ist jeweils eine minimale Sektion der Form
APF-Konfiguration
[my_cache_instance] Cache.Provider.Namespace = "" Cache.Provider.Class = "" Cache.Active = ""
anzulegen. Cache.Provider.Namespace definiert den Namespace und Cache.Provider.Class den Namen des zu verwendenden Cache-Providers. Die Diretive Cache.Active definiert, ob der Caching-Mechanismus aktiv ist oder nicht. Hierbei befindet sich der CacheManager im Status "aktiv", wenn die Direktive "true" beinhaltet.

Je nach Provider müssen weitere Parameter definiert werden. Diese können in den folgenden Kapiteln nachgelesen werden.


2. Anwendung

Da es möglich sein soll, mehrere Cache-Manager-Instanzen innerhalb einer Anwendung zu verwenden wurde eine Factory zur Erzeugung und Verwaltung der konkreten Instanzen eineführt. Diese besitzt die Methode getCacheManager() um einen für den gewünschten Anwendungsfall konfigurierten CacheManager zu erzeugen. Die CacheManagerFabric wird dabei als Singleton erzeugt um bei einem erneuten Aufruf der Komponente keinen Initialisierungsaufwand mehr betreiben zu müssen - Caching muss schließlich performant sein!

Die folgende Code-Box zeigt einen typischen Anwendungsfall des CacheManagers:
PHP-Code
$cMF = &$this->__getServiceObject('tools::cache','CacheManagerFabric'); $cM = &$cMF->getCacheManager('{config_section}'); $cacheKey = 'my_cache_key'; $cacheContent = $cM->getFromCache($cacheKey); if($cacheContent === null){ $cacheContent = /* generate content */; $cM->writeToCache($cacheKey,$cacheContent); } // clear cache if necessary if(/* ... */){ if(/* ... */){ $cM->clearCache($cacheKey); // clean only the desired cache content } else{ $cM->clearCache(); // clean the entire namespace } }
Wie dem Beispiel bereits zu entnehmen ist, besitzt der CacheManager drei Methoden, die jeweils vom zuständigen Provider implementiert werden:
  • getFromCache(): Liest den gewünschten Cache-Inhalt. Ist für den Cache-Key noch kein Inhalt vorhanden, wird null zurückgegeben. Dies kann gleichzeitig als Indiz für das Neuanlegen des Cache-Inhalts verwendet werden.
  • writeToCache(): Schreibt den Inhalt unter dem konfigurierten Namespace und dem übergebenen Cache-Key in den Cache. Bei Erfolg wird true, bei einem Fehler false zurückgegeben.
  • clearCache(): Die Methode clearCache() dient zum Löschen des Caches. Hierbei können durch Übergabe des gewünschten Cache-Keys dieser selbst, oder ohne Argument, der komplette Namespace gelöscht werden.


3. Mitgelieferte Provider

Das Framework liefert bereits vier fertige Provider mit. Diese decken die typischen Anwendungsfälle ab. Sollte für einen definierten Anwendungsfall kein Provider enthalten sein, können diese wie in Kapitel 4 beschrieben erweitert werden.


3.1. Text-Cache Provider

Der Text-Cache-Provider implementiert ein einfaches Filesystem-Caching. Hierbei wird unter einem definierten Basis-Pfad der gewünschte Cache-Inhalt strukturiert abgelegt. Als erstes Strukturelement wird der Namespace eingesetzt, gefolgt von einem weiteren Unterordner aus den ersten beiden Zeichen des md5-Schlüssels des Cache-Keys.

Um den Provider verwenden zu können, muss die referenzierte Konfigurationssektion wir folgt aufgebaut sein:
APF-Konfiguration
[text_cache] Cache.Provider.Namespace = "tools::cache::provider" Cache.Provider.Class = "TextCacheProvider" Cache.Active = "" Cache.BaseFolder = "" Cache.Namespace = ""
Cache.BaseFolder beinhaltet den Pfad zum vom CacheManager verwalteten Ordner, das Attribut Cache.Namespace benennet das erste Strukturelement. Bitte beachten Sie, dass Abschnitte des Namespaces jeweils durch "::" getrennt notiert werden sollten.

Hinweis: Der Text-Cache-Provider verwendet den FilesystemManager für die Verwaltung des Cache-Ordners. Aus diesem Grund muss der Benutzer, unter dem der Webserver läuft Schreibrechte für diesen Ordner besitzen.


3.2. Objekt-Cache Provider

Der Objekt-Cache-Provider ist eine Erweiterung des unter 3.1. beschriebenen Text-Caches. Zur Ablage der Cache-Dateien wird ebenfalls ein Ordner auf dem Dateisystem verwendet. Der Unterschied besteht darin, dass die als Cache-Content übergebenen Werte serialisiert auf der Platte vorgehalten werden. Hierdurch ist es möglich, einen Filesystem-basierten Objekt-Cache aufzubauen.

Die Dafür notwendige Konfigurationssektion gestaltet sich wie folgt:
APF-Konfiguration
[object_cache] Cache.Provider.Namespace = "tools::cache::provider" Cache.Provider.Class = "ObjectCacheProvider" Cache.Active = "" Cache.BaseFolder = "" Cache.Namespace = ""

3.3. Mem-Cache Provider

Der Mem-Cache-Provider bietet die Möglichkeit, PHP-Objekte im memcached-Server vorzuhalten. Hierbei wird das jeweilige PHP-Objekt beim Schreiben des Caches serialisiert und beim Lesen deserialisiert. Bitte beachten Sie, dass hierdurch Objekt-Inhalte vom Typ Ressource verloren gehen und nach dem Deserialisieren neu initialisiert werden müssen.

Für den Zugriff auf einen memcached-Server ist folgende Konfiguration vorzuhalten:
APF-Konfiguration
[mem_cache] Cache.Provider.Namespace = "tools::cache::provider" Cache.Provider.Class = "MemCacheProvider" Cache.Active = "" Cache.Host = "" Cache.Port = "" Cache.PersistentConnect = "" Cache.Namespace = ""
Die Implementierung des MemCacheProviders beinhaltet - trotz der Tatsache, dass die memcache_*() keine Namespaces kennt - ebenfalls einen Namespace-Support. Dieser wird über ein Präfix im Cache-Key abgebildet. Damit ist es wie bei den bisherigen Provider-Implementierungen möglich, komplette Namespaces zu löschen.

Hinweis: Für den Einsatz des MemCacheProviders ist die PHP-Erweiterung memcache erforderlich!


3.4. Datenbank-Cache Provider

Der DBCacheProvider nutzt eine Datenbank-Tabelle zur Ablage der Cache-Informationen. Um diesen nutzen zu können, muss folgende Konfiguration vorgehalten werden:
APF-Konfiguration
[database_cache] Cache.Provider.Namespace = "tools::cache::provider" Cache.Provider.Class = "DBCacheProvider" Cache.Active = "" Cache.Connection = "" Cache.Table = "" Cache.Namespace = ""
Cache.Connection beinhaltet den Connection-Key, der dazu verwendet wird um über den ConnectionManager eine Verbindung zu einer Datenbank zu erzeugen. Hierzu muss eine korrespondierende Datenbank-Verbindung wie in der Klassenreferenz aufgeührten Weise angelegt werden. Cache.Table definiert den Namen der Cache-Tabelle, die mit folgendem Statement erzeugt werden sollte:
Code
CREATE TABLE `database_cache` ( `CacheID` int(5) NOT NULL auto_increment, `namespace` varchar(100) NOT NULL default '', `cachekey` varchar(100) NOT NULL default '', `value` text NOT NULL, PRIMARY KEY (`CacheID`), KEY `cachevalues` (`namespace`,`cachekey`) );
Bitte beachten Sie, dass die Benennung der Spalten namespace, cachekey und value bindend ist.


4. Erweiterung

Die Implementierung des CacheManagers sieht mehrere Komponenten vor. Zur Erzeugung des CacheManagers wird die CacheManagerFabric eingesetzt, die die konkreten CacheManager-Instanzen erzeugt, initialisiert und für die weitere Verwendung vorhält. Der CacheManager selbst übernimmt die Initialisierung der gewünschten Provider und bietet die in Kapitel 2 beschrieben Methoden. Jeder Provider implementiert dabei die in der abstrakten Klasse AbstractCacheProvider definierten Methoden read(), write() und clear(). Diesen wird jeweils der gewünschte Cache-Key und ggf. der zu schreibende Inhalt übergeben. Die Konfigurationsparameter stehen innerhalb der Methoden über die private Funktion __getCacheConfigAttribute() zur Verügung, die den Namen des Attributes erwartet. Zur Betriebssicherung wird ein Fehler ausgegeben, sollte die gewünschte Konfigurationsdirektive nicht vorhanden oder leer sein. Details zur Klassendefinition kann der API-Dokumentation unter Downloads entnommen werden.

Da ein Cache-Provider über seinen Namespace und seinen Klassennamen adressiert wird, kann dieser in einem beliebigen Namespace (z.B. der Namespace der Applikation) abgelegt werden. Der Rumpf eines eigenen Providers gestaltet sich wie folgt:
PHP-Code
class MyCacheProvider extends AbstractCacheProvider { function MyCacheProvider(){ } function read($cacheKey){ } function write($cacheKey,$content){ } function clear($cacheKey = null){ } }
Die erwarteten Rückgabe-Werte sind der API-Dokumentation der Klasse AbstractCacheProvider zu entnehmen. Sollen Funktionen der bestehenden Provider genutzt werden, besteht weiterhin die Mögichkeit von diesen abzuleiten. Dieses Mittel wird bereits intern für die Implementierung des ObjectCacheProvider genutzt, da dieser ebenso einen dedizierten Ordner für die Ablage der Objekt-Cache-Dateien nutzt.

Die folgende Code-Box zeigt die Implementierung eines Cache-Providers für das Cachen von Image-Ressourcen:
PHP-Code
class PNGImageCacheProvider extends TextCacheProvider { function PNGImageCacheProvider(){ } function read($cacheKey){ $cacheFile = $this->__getCacheFile($cacheKey); if(!file_exists($cacheFile)){ return null; } else{ return createimagefrompng($cacheFile); } } function write($cacheKey,$img){ $cacheFile = $this->__getCacheFile($cacheKey); FilesystemManager::createFolder(dirname($cacheFile)); imagepng($img,$cacheFile); } function clear($cacheKey = null){ if($cacheKey === null){ $baseFolder = $this->__getCacheConfigAttribute('Cache.BaseFolder'); FilesystemManager::deleteFolder($baseFolder,true); } else{ $cacheFile = $this->__getCacheFile($cacheKey); FilesystemManager::removeFile($cacheFile); } } }

Kommentare

Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.