hab heut wieder etwas gebastelt und will euch das nicht vorenthalten. zum einen ETag support, zum anderen einen page-cache. weiters will ich hier gleich generell die caching-mechanismen in webtek erlaeutern:
Es gibt folgende arten von cache:
- macro-cache
- model-cache
- page-cache
- ETag (= caching auf client-seite)
Macro-Cache
um den output eines macros zu cachen, wird einfach das code-attribute Cache angegeben. alternativ kann auch noch eine zeit definiert werden. z.b.
sub posts :Macro :Cache { ... }
sub posts :Macro :Cache(300) { ... } # cached fuer 5min
Model-Cache
dieser cache erlaubt model-suchabfragen zu cachen. dieses gilt aber nur fuer die find_one methode. wenn man z.b. folgende abfrage cachen will:
my $user = app->Model->User->find_one('nickname' => 'max');
dann muss man folgenden code in das User-Model schreiben:
use WebTek::Cache qw( nickname );
folgende definition erlaubt folgende (gecache'te) abfragen:
use WebTek::Cache qw( id nickname street,zipcode );
...
my $user = app->Model->User->find_one('id' => 123);
my $user = app->Model->User->find_one('nickname' => 'max');
my $user = app->Model->User->find_one(
'street' => $street,
'zipcode' => $zipcode
);
wenn man das $user object aendert (sprich ein $user->update(%params) macht), wird selbstverstaendlich jeglicher cache geloescht. d.h. bei der naechsten abfrage wird das model neu von der datenbank geholt, und in den cache geschrieben. weiters ist zu beachten, wenn man den protoypen von User aendert (z.b. neue db-column), dass man auch den cache loescht, da dieser sonnst natuerlich noch die alten objekte zurueckliefert!
Page-Cache
heute neu dazugekommen ist der page-cache, welcher es erlaubt gleich ganze seiten zu cachen. hierfuer einfach das Cache attribute (wieder optional mit der zeit, defaultwert ist 1min) bei der action dazufuegen.
sub rss :Action :Cache { ... }
sub rss :Action :Cache(60) { ... }
weiters zu beachten:
- dieser cache ist hauptsaechlich dafuer da, um peaks auf eine bestimme url zu "verkraften", nicht um die halbe applikation im cache zu halten (obwohl das auch funktioniert)
- der cache funktioniert nur fuer requests welche ohne einen session->user sind, da meist bei eingeloggten requests die seite viel zu dynamisch ist, um einen cache effektiv arbeiten zu lassen.
- als (teil vom) cachekey wird die komplette URI verwendet. d.h.
/weblog/rss /weblog/rss?page=2
sind zwei verschiedene cache eintraege.
ETag's
Ein Etag ist ein unique-key fuer eine url, welchen der client bei jedem request dieser url an den server uebermittelt. der server generiert nun fuer diese url seinen eigenen key, und wenn diese zwei uebereinstimmen schickt der server ein http-status 304 (= not modified) retour. damit man diese funktionalitaet in webtek verwenden kann muessen einfach nur die abhaenigkeiten ermittelt werden, wann sich client-cache out-of-date ist. klingt vielleicht kompliziert, ist es aber meist nicht.
z.b. wenn wir ein posting anzeigen wollen:
sub index :Action :ETag($self->post->modify_time) { ... }
reicht meist schon aus, um festzustellen, ob der client noch die aktuelle version im cache hat. man kann auch einfach mehr abhaenigkeiten definieren:
sub index :Action
:ETag($self->post->modify_time)
:ETag($self->post->comment_count)
{
...
}
Nachtrag
zu guter letzt noch die antwort auf die frage wo webtek daten cached. mit dabei ist schon ein client fuer memcached, welches einfach in der config/cache.config datei aktiviert wird:
{
#... define the class which should be used for caching
'class' => 'WebTek::Cache::Memcached',
#... config settings for WebTek::Cache::Memcached
'WebTek::Cache::Memcached' => {
'servers' => [ '127.0.0.1:11211' ],
},
}
man kann auch eigene Cache klassen verwenden solange sie:
- eine subclasse von WebTek::Cache sind
- und folgende methoden besitzten
- new
- set($key, $value, $expire_time)
- add($key, $value, $expire_time)
- get($key)
- delete($key)
1 Kommentar(e):
Neuen Kommentar schreiben: