Documentation for C::P::Cache
Yuval Kogman [Thu, 22 Jun 2006 08:28:25 +0000 (08:28 +0000)]
lib/Catalyst/Plugin/Cache.pm
lib/Catalyst/Plugin/Cache/Curried.pm

index 9e73ce0..c4cc4ae 100644 (file)
@@ -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</META DATA> for details.
+
+=item curry_cache %meta
+
+Return a L<Catalyst::Plugin::Cache::Curried> object, curried with %meta.
+
+See L</META DATA> for details.
+
+=item cache_set $key, $value, %meta
+
+=item cache_get $key, %meta
+
+=item cache_remove $key, %meta
+
+These cache operations will call L<choose_cache_backend> with %meta, and then
+call C<set>, C<get> or C<remove> 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<default_cache_backend> 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<Catalyst::Engine>. 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<backend> key which can be used to explicitly choose a backend
+by name.
+
+The C<choose_cache_backend> method can be overridden in order to facilitate
+more intelligent backend selection. For example,
+L<Catalyst::Plugin::Cache::Choose::KeyRegexes> overrides that method to select
+a backend based on key regexes.
+
+Another example is a L<Catalyst::Plugin::Cache::ControllerNamespacing>, 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</Cache
+Profiles> configuratrion.
+
+=head2 Meta Data Keys
+
+C<choose_cache_backend> is called with some default keys.
+
+=over 4
+
+=item key
+
+Supplied by C<cache_get>, C<cache_set> and C<cache_remove>.
+
+=item value
+
+Supplied by C<cache_set>
+
+=item caller
+
+The package name of the innermost caller that doesn't match
+C<qr/Plugin::Cache/>.
+
+=item caller_frame
+
+The entire C<caller($i)> frame of C<caller>.
+
+=item component
+
+The package name of the innermost caller who C<isa> L<Catalyst::Component>.
+
+=item component_frame
+
+This entire C<caller($i)> frame of C<component>.
+
+=item controller
+
+The package name of the innermost caller who C<isa> L<Catalyst::Controller>.
+
+=item controller_frame
+
+This entire C<caller($i)> frame of C<controller>.
+
+=back
+
+=head2 Meta Data Currying
+
+In order to avoid specifying %meta over and over again you may call C<cache> or
+C<curry_cache> with %meta once, and get back a B<curried cache object>. This
+object responds to the methods C<get>, C<set> and C<remove>, by appending it's
+captured meta data and delegating them to C<cache_get>, C<cache_set> and
+C<cache_remove>.
+
+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<Catalyst::Plugin::Cache::Curried> for details.
+
 =head1 CONFIGURATION
 
-  $c->config->{cache} = {
-    backend => '',
-  };
+    $c->config->{cache} = {
+        ...
+    };
 
 All configuration parameters should be provided in a hash reference under the
 C<cache> key in the C<config> hash.
 
+=head2 Backend Configuration
+
+Configuring backend objects is done by adding hash entries under the
+C<backends> keys in the main config.
+
+A special case is that the hash key under the C<backend> (singular) key of the
+main config is assumed to be the backend named C<default>.
+
 =over 4
 
 =item class
 
-Load an entire set of Caching modules.
+Instantiate a backend from a L<Cache> 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<new> method.
 
-=item backends
+The class will be C<required> 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<Catalyst> applications. For example
+L<Catalyst::Plugin::Cache::Store::FastMmap> will specify a default
+C<share_file>, and additionally use a subclass of L<Cache::FastMmap> that can
+also store non reference data.
+
+The store plugin must be loaded.
+
+=back
 
-The currying class you are using, defaults to L<Catalyst::Plugin::Cache::Curried>.
+=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<cache>
+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<store> 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');
index 277e3a1..76f6c87 100644 (file)
@@ -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<cache_get> and C<cache_remove> 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<Catalyst::Plugin::Cache/META DATA> 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<choose_cache_backend> 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<c> object's C<cache_set>, C<cache_get> or C<cache_remove>
+with the arguments, then the captured meta from C<meta>, and then the
+additional meta.
+
+=item meta
+
+Returns the array ref that captured %meta from C<new>.
+
+=item c
+
+The captured $c object to delegate to.
+
+=back
+
 =cut