am 9. Dezember 2009
Ich bin wieder da! Ok, die meisten werden sich jetzt wohl fragen “der Nils war weg?”. Aber ja, die letzten zwei Wochen haben meine lieben Co-Autoren mir unter die Arme gegriffen und zehn sehr interessante Artikel verfasst. Deswegen gilt natürlich an alle, die den Blog in der Zeit unterstützt haben ein besonderer Dank. Ohne euch hätte ich das “jeder-Tag-ein-Artikel” Konzept nicht durchhalten können.
Jetzt aber wieder zurück in die Realität und was zum Thema Caching geschrieben. Wie ihr wisst, habe ich ja zusammen mit Mike in der letzten Ausgabe des PHP Magazin ein wenig zu diesem Thema erzählt. Natürlich konnten wir nicht alle Aspekte dieses doch recht komplexen Themas aufführen. Aus diesem Grund will ich heute mal über eine Technik erzählen, die stale-if-error heißt.
Prinzipiell ist es ganz einfach. Ich habe einen Cache, den ich nach einem Ergebis abfrage. Falls das Ergebnis nicht in meinem Zwischenspeicher vorhanden ist, so sagt mir mein Cache dies und ich muss mich halt neu drum kümmern. So weit so gut. Falls bei meiner neuen Berechnung nun ein Fehler auftritt, weil vielleicht nicht alle benötigten Daten zu diesem Zeitpunkt vorhanden sind, so müsste ich jetzt einen Fehler ausgeben. Die Idee hinter stale-if-error ist die, dass man in einem solchen Fall keinen Error anzeigt, sondern einfach die zuletzt gültigen Daten ausliefert, auch wenn sie per Definition nicht mehr gültig sind, also das expire Date erreicht wurde. Ein SQUID zum Beispiel kann so konfiguriert werden, dass es sich so verhält. Sollte man auch so verwenden, wenn man “normale” Webanwendungen baut.
Bei Web-Caches gibt es dieses Verhalten also. So viel wir ich weiß übernehmen viele andere Caches dieses Prinzip leider nicht. Falls ich eine “lifetime” für meine gespeicherten Werte angebe, so habe ich oft nicht die Möglichkeit an meine Daten dran zu kommen, falls die Lebenszeit abgelaufen ist. Eigentlich schade, denn in einigen Fällen möchte ich trotzdem dran kommen, denn es ist das beste, was ich zu diesem Zeitpunkt habe. Das ganze könnte so oder so ähnlich aussehen:
$cache = new PHM_BestCacheEver( );
if ( $cache->has( 'name' ) ) {
$name = $cache->get( 'name' );
}else{
try {
$name = calculateName( );
$cache->set( 'name', '$name', '1 day' );
}catch( CalculationException $e ){
$name = $cache->getLastValid( 'name' );
}
}
Ich weiß nicht, ob das jetzt für alle nachvollziehbar ist, aber ich denke schon. Wir müssen also nur eine Möglichkeit bauen, dass wir trotz der abgelaufenen Lebenszeit noch an die Daten kommen.
Mein Einsatzgebiet für diese Funktionalität könnt ihr euch vielleicht schon denken. Ich verwendet den Zend Cache, um meine Twitter Follower anzuzeigen. Das Problem dabei ist, dass die API nur 100 Request pro Stunde abkann, danach liefer die Schnittstelle halt keine Daten zurück. Was darin resulultiert, dass keine Follower mehr angezeigt werden. Doofe Sache.
Noch kurz als Nachtrag, da ich es gerade gefunden habe, einen passenden Ausschnitt auf einem RFC zu dem Thema:
HTTP [RFC2616] requires that caches "respond to a request with the
most up-to-date response held... that is appropriate to the request,"
although "in carefully controlled circumstances" a stale response is
allowed to be returned.