From: Yuval Kogman Date: Thu, 22 Jun 2006 08:28:25 +0000 (+0000) Subject: Documentation for C::P::Cache X-Git-Tag: v0.01~7 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Plugin-Cache.git;a=commitdiff_plain;h=85a748b91e5aa774ea6e55b3003dc2089997c0db Documentation for C::P::Cache --- diff --git a/lib/Catalyst/Plugin/Cache.pm b/lib/Catalyst/Plugin/Cache.pm index 9e73ce0..c4cc4ae 100644 --- a/lib/Catalyst/Plugin/Cache.pm +++ b/lib/Catalyst/Plugin/Cache.pm @@ -54,7 +54,7 @@ sub setup_cache_backends { if ( !$app->get_cache_backend("default") ) { local $@; eval { $app->setup_generic_cache_backend( default => $app->get_default_cache_backend_config || {} ) }; - } + } } sub default_cache_store { @@ -182,17 +182,23 @@ sub _cache_caller_meta { for my $i ( 0 .. 15 ) { # don't look to far my @info = caller(2 + $i) or last; - $caller ||= \@info unless $info[0] =~ /Catalyst::Plugin::Cache/; + $caller ||= \@info unless $info[0] =~ /Plugin::Cache/; $component ||= \@info if $info[0]->isa("Catalyst::Component"); $controller ||= \@info if $info[0]->isa("Catalyst::Controller"); last if $caller && $component && $controller; } + my ( $caller_pkg, $component_pkg, $controller_pkg ) = + map { $_ ? $_->[0] : undef } $caller, $component, $controller; + return ( - 'caller' => $caller, - component => $component, - controller => $controller, + 'caller' => $caller_pkg, + component => $component_pkg, + controller => $controller_pkg, + caller_frame => $caller, + component_frame => $component, + controller_frame => $controller, ); } @@ -255,7 +261,7 @@ __END__ =head1 NAME -Catalyst::Plugin::Cache - +Catalyst::Plugin::Cache - Flexible caching support for Catalyst. =head1 SYNOPSIS @@ -264,12 +270,10 @@ Catalyst::Plugin::Cache - /; # configure a backend or use a store plugin - __PACKAGE__->config( cache => { - backend => { - class => "Cache::Bounded", - # ... params ... - }, - }); + __PACKAGE__->config->{cache}{backend} = { + class => "Cache::Bounded", + # ... params ... + }; # ... in a controller @@ -295,43 +299,248 @@ Amongst it's features are support for multiple backends, segmentation based on component or controller, keyspace partitioning and so forth, in various sub plugins. +=head1 METHODS + +=over 4 + +=item cache $profile_name + +=item cache %meta + +Return a curried object with meta data from $profile_name or as explicitly +specified. + +If a profile by the name $profile_name doesn't exist but a backend object by +that name does exist, the backend will be returned instead, since the interface +for curried caches and backends is almost identical. + +This method can also be called without arguments, in which case is treated as +though the %meta hash was empty. + +See L for details. + +=item curry_cache %meta + +Return a L object, curried with %meta. + +See L for details. + +=item cache_set $key, $value, %meta + +=item cache_get $key, %meta + +=item cache_remove $key, %meta + +These cache operations will call L with %meta, and then +call C, C or C on the resulting backend object. + +=item choose_cache_backend %meta + +Select a backend object. This should return undef if no specific backend was +selected - it's caller will handle getting C on it's own. + +This method is typically used by plugins. + +=item get_cache_backend $name + +Get a backend object by name. + +=item default_cache_backend + +Return the default backend object. + +=item temporary_cache_backend + +When no default cache backend is configured this method might return a backend +known to work well with the current L. This is a stup. + +=item + +=back + +=head1 META DATA + +=head2 Introduction + +Whenever you set or retrieve a key you may specify additional meta data that +will be used to select a specific backend. + +This metadata is very freeform, and the only key that has any meaning by +default is the C key which can be used to explicitly choose a backend +by name. + +The C method can be overridden in order to facilitate +more intelligent backend selection. For example, +L overrides that method to select +a backend based on key regexes. + +Another example is a L, which +that wraps backends in objects that perform key mangling, in order to keep +caches namespaced per controller. + +However, this is generally left as a hook for larger, more complex +applications. Most configurations should make due + +The simplest way to dynamically select a backend is based on the L configuratrion. + +=head2 Meta Data Keys + +C is called with some default keys. + +=over 4 + +=item key + +Supplied by C, C and C. + +=item value + +Supplied by C + +=item caller + +The package name of the innermost caller that doesn't match +C. + +=item caller_frame + +The entire C frame of C. + +=item component + +The package name of the innermost caller who C L. + +=item component_frame + +This entire C frame of C. + +=item controller + +The package name of the innermost caller who C L. + +=item controller_frame + +This entire C frame of C. + +=back + +=head2 Meta Data Currying + +In order to avoid specifying %meta over and over again you may call C or +C with %meta once, and get back a B. This +object responds to the methods C, C and C, by appending it's +captured meta data and delegating them to C, C and +C. + +This is simpler than it sounds. + +Here is an example using currying: + + my $cache = $c->cache( %meta ); # cache is curried + + $cache->set( $key, $value ); + + $cache->get( $key ); + +And here is an example without using currying: + + $c->cache_set( $key, $value, %meta ); + + $c->cache_get( $key, %meta ); + +See L for details. + =head1 CONFIGURATION - $c->config->{cache} = { - backend => '', - }; + $c->config->{cache} = { + ... + }; All configuration parameters should be provided in a hash reference under the C key in the C hash. +=head2 Backend Configuration + +Configuring backend objects is done by adding hash entries under the +C keys in the main config. + +A special case is that the hash key under the C (singular) key of the +main config is assumed to be the backend named C. + =over 4 =item class -Load an entire set of Caching modules. +Instantiate a backend from a L compatible class. E.g. -=item backend + $c->config->{cache}{backends}{small_things} = { + class => "Cache::Bounded", + interval => 1000, + size => 10000, + }; + + $c->config->{cache}{backends}{large_things} = { + class => "Cache::Memcached::Mangaed", + data => '1.2.3.4:1234', + }; -The specific backend you want to use. +The options in the hash are passed to the class's C method. -=item backends +The class will be C as necessary during setup time. -A hashref with backend names as keys, and module names as values. One of these -should have the key "default" to indicate the default backend. +=item store -=item default_store +Instrantiate a backend using a store plugin, e.g. -The store you are using. This must be supplied if you have loaded multiple -store plugins. + $c->config->{cache}{backend} = { + store => "FastMmap", + }; -=item curried_class +Store plugins typically require less configuration because they are specialized +for L applications. For example +L will specify a default +C, and additionally use a subclass of L that can +also store non reference data. + +The store plugin must be loaded. + +=back -The currying class you are using, defaults to L. +=head2 Cache Profiles + +=over 4 =item profiles -Supply your own predefined profiles for cache namespacing. - +Supply your own predefined profiles for cache metadata, when using the C +method. + +For example when you specify + + $c->config->{cache}{profiles}{thumbnails} = { + backend => "large_things", + }; + +And then get a cache object like this: + + $c->cache("thumbnails"); + +It is the same as if you had done: + + $c->cache( backend => "large_things" ); + +=back + +=head2 Misc Configuration + +=over 4 + +=item default_store + +When you do not specify a C parameter in the backend configuration this +one will be used instead. This configuration parameter is not necessary if only +one store plugin is loaded. =back @@ -352,6 +561,11 @@ A plugin that provides backends of a certain type. This is a bit like a factory. Stored key/value pairs of data for easy re-access. +=item meta data + +"extra" information about the item being stored, which can be used to locate an +appropriate backend. + =item curried cache my $cache = $c->cache(type => 'thumbnails'); diff --git a/lib/Catalyst/Plugin/Cache/Curried.pm b/lib/Catalyst/Plugin/Cache/Curried.pm index 277e3a1..76f6c87 100644 --- a/lib/Catalyst/Plugin/Cache/Curried.pm +++ b/lib/Catalyst/Plugin/Cache/Curried.pm @@ -25,22 +25,22 @@ sub new { } sub backend { - my ( $self, $key ) = @_; - $self->c->choose_cache_backend( @{ $self->meta }, key => $key ) + my ( $self, @meta ) = @_; + $self->c->choose_cache_backend( @{ $self->meta }, key => $key, @meta ) } sub set { - my ( $self, $key, $value ) = @_; - $self->c->cache_set( $key, $value, @{ $self->meta } ); + my ( $self, $key, $value, @meta ) = @_; + $self->c->cache_set( $key, $value, @{ $self->meta }, @meta ); } sub get { - my ( $self, $key ) = @_; + my ( $self, $key, @meta ) = @_; $self->c->cache_get( $key, @{ $self->meta } ); } sub remove { - my ( $self, $key ) = @_; + my ( $self, $key, @meta ) = @_; $self->c->cache_remove( $key, @{ $self->meta } ); } @@ -57,9 +57,47 @@ C and C that look more like a backend. =head1 SYNOPSIS + my $curried = $c->cache( %meta ); + + $curried->get( $key, $value ); # no need to specify %meta =head1 DESCRIPTION +See L for details. + +=head1 METHODS + +=over 4 + +=item new %meta + +Create a new curried cache, that captures C<%meta>. + +=item backend %additional_meta + +This calls C on the $c object with the captured meta and +the additional meta. + +=item set $key, $value, %additional_meta + +=item get $key, %additional_meta + +=item remove $key, %additional_meta + +Dellegate to the C object's C, C or C +with the arguments, then the captured meta from C, and then the +additional meta. + +=item meta + +Returns the array ref that captured %meta from C. + +=item c + +The captured $c object to delegate to. + +=back + =cut