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.
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.
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.
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.
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.
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 = ""
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!
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.
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.