C::P::Cache doc fixing (mechanical only, not content)
[catagits/Catalyst-Plugin-Cache.git] / lib / Catalyst / Plugin / Cache.pm
1 #!/usr/bin/perl
2
3 package Catalyst::Plugin::Cache;
4 use base qw/Class::Data::Inheritable Class::Accessor::Fast/;
5
6 use strict;
7 use warnings;
8
9 use Scalar::Util ();
10 use Catalyst::Utils ();
11 use Carp ();
12 use NEXT;
13
14 use Catalyst::Plugin::Cache::Curried;
15
16 __PACKAGE__->mk_classdata( "_cache_backends" );
17 __PACKAGE__->mk_accessors( "_default_curried_cache" );
18
19 sub setup {
20     my $app = shift;
21
22     # set it once per app, not once per plugin,
23     # and don't overwrite if some plugin was wicked
24     $app->_cache_backends({}) unless $app->_cache_backends;
25
26     my $ret = $app->NEXT::setup( @_ );
27
28     $app->setup_cache_backends;
29
30     $ret;
31 }
32
33 sub get_default_cache_backend_config {
34     my ( $app, $name ) = @_;
35     $app->config->{cache}{backend} || $app->get_cache_backend_config("default");
36 }
37
38 sub get_cache_backend_config {
39     my ( $app, $name ) = @_;
40     $app->config->{cache}{backends}{$name};
41 }
42
43 sub setup_cache_backends {
44     my $app = shift;
45
46     # give plugins a chance to find things for themselves
47     $app->NEXT::setup_cache_backends;
48
49     foreach my $name ( keys %{ $app->config->{cache}{backends} } ) {
50         next if $app->get_cache_backend( $name );
51         $app->setup_generic_cache_backend( $name, $app->get_cache_backend_config( $name ) || {} );
52     }
53
54     if ( !$app->get_cache_backend("default") ) {
55         local $@;
56         eval { $app->setup_generic_cache_backend( default => $app->get_default_cache_backend_config || {} ) };
57    }
58 }
59
60 sub default_cache_store {
61     my $app = shift;
62     $app->config->{cache}{default_store} || $app->guess_default_cache_store;
63 }
64
65 sub guess_default_cache_store {
66     my $app = shift;
67
68     my @stores = map { /Cache::Store::(.*)$/ ? $1 : () } $app->registered_plugins;
69
70     if ( @stores == 1 ) {
71         return $stores[0];
72     } else {
73         Carp::croak "You must configure a default store type unless you use exactly one store plugin.";
74     }
75 }
76
77 sub setup_generic_cache_backend {
78     my ( $app, $name, $config ) = @_;
79     my %config = %$config;
80
81     if ( my $class = delete $config{class} ) {
82         $app->setup_cache_backend_by_class( $name, $class, %config );
83     } elsif ( my $store = delete $config->{store} || $app->default_cache_store ) {
84         my $method = lc("setup_${store}_cache_backend");
85
86         Carp::croak "You must load the $store cache store plugin (if it exists). ".
87         "Please consult the Catalyst::Plugin::Cache documentation on how to configure hetrogeneous stores."
88             unless $app->can($method);
89
90         $app->$method( $name, %config );
91     } else {
92         $app->log->warn("Couldn't setup the cache backend named '$name'");
93     }
94 }
95
96 sub setup_cache_backend_by_class {
97     my ( $app, $name, $class, @args ) = @_;
98     Catalyst::Utils::ensure_class_loaded( $class );
99     $app->register_cache_backend( $name => $class->new( @args ) );
100 }
101
102 # end of spaghetti setup DWIM
103
104 sub cache {
105     my ( $c, @meta ) = @_;
106
107     if ( @meta == 1 ) {
108         my $name = $meta[0];
109         return ( $c->get_preset_curried($name) || $c->get_cache_backend($name) );
110     } elsif ( !@meta ) {
111         # be nice and always return the same one for the simplest case
112         return ( $c->_default_curried_cache || $c->_default_curried_cache( $c->curry_cache( @meta ) ) );
113     } else {
114         return $c->curry_cache( @meta );
115     }
116 }
117
118 sub construct_curried_cache {
119     my ( $c, @meta ) = @_;
120     return $c->curried_cache_class( @meta )->new( @meta );
121 }
122
123 sub curried_cache_class {
124     my ( $c, @meta ) = @_;
125     $c->config->{cache}{curried_class} || "Catalyst::Plugin::Cache::Curried";
126 }
127
128 sub curry_cache {
129     my ( $c, @meta ) = @_;
130     return $c->construct_curried_cache( $c, $c->_cache_caller_meta, @meta );
131 }
132
133 sub get_preset_curried {
134     my ( $c, $name ) = @_;
135
136     if ( ref( my $preset = $c->config->{cache}{profiles}{$name} ) ) {
137         return $preset if Scalar::Util::blessed($preset);
138
139         my @meta = ( ( ref $preset eq "HASH" ) ? %$preset : @$preset );
140         return $c->curry_cache( @meta );
141     }
142
143     return;
144 }
145
146 sub get_cache_backend {
147     my ( $c, $name ) = @_;
148     $c->_cache_backends->{$name};
149 }
150
151 sub register_cache_backend {
152     my ( $c, $name, $backend ) = @_;
153
154     no warnings 'uninitialized';
155     Carp::croak("$backend does not look like a cache backend - "
156     . "it must be an object supporting get, set and remove")
157         unless eval { $backend->can("get") && $backend->can("set") && $backend->can("remove") };
158
159     $c->_cache_backends->{$name} = $backend;
160 }
161
162 sub unregister_cache_backend {
163     my ( $c, $name ) = @_;
164     delete $c->_cache_backends->{$name};
165 }
166
167 sub default_cache_backend {
168     my $c = shift;
169     $c->get_cache_backend( "default" ) || $c->temporary_cache_backend;
170 }
171
172 sub temporary_cache_backend {
173     my $c = shift;
174     die "FIXME - make up an in memory cache backend, that hopefully works well for the current engine";
175 }
176
177 sub _cache_caller_meta {
178     my $c = shift;
179
180     my ( $caller, $component, $controller );
181     
182     for my $i ( 0 .. 15 ) { # don't look to far
183         my @info = caller(2 + $i) or last;
184
185         $caller     ||= \@info unless $info[0] =~ /Plugin::Cache/;
186         $component  ||= \@info if $info[0]->isa("Catalyst::Component");
187         $controller ||= \@info if $info[0]->isa("Catalyst::Controller");
188     
189         last if $caller && $component && $controller;
190     }
191
192     my ( $caller_pkg, $component_pkg, $controller_pkg ) =
193         map { $_ ? $_->[0] : undef } $caller, $component, $controller;
194
195     return (
196         'caller'   => $caller_pkg,
197         component  => $component_pkg,
198         controller => $controller_pkg,
199         caller_frame     => $caller,
200         component_frame  => $component,
201         controller_frame => $controller,
202     );
203 }
204
205 # this gets a shit name so that the plugins can override a good name
206 sub choose_cache_backend_wrapper {
207     my ( $c, @meta ) = @_;
208
209     Carp::croak("metadata must be an even sized list") unless @meta % 2 == 0;
210
211     my %meta = @meta;
212
213     unless ( exists $meta{'caller'} ) {
214         my %caller = $c->_cache_caller_meta;
215         @meta{keys %caller} = values %caller;
216     }
217     
218     # allow the cache client to specify who it wants to cache with (but loeave room for a hook)
219     if ( exists $meta{backend} ) {
220         if ( Scalar::Util::blessed($meta{backend}) ) {
221             return $meta{backend};
222         } else {
223             return $c->get_cache_backend( $meta{backend} ) || $c->default_cache_backend;
224         }
225     };
226     
227     if ( my $chosen = $c->choose_cache_backend( %meta ) ) {
228         $chosen = $c->get_cache_backend( $chosen ) unless Scalar::Util::blessed($chosen); # if it's a name find it
229         return $chosen if Scalar::Util::blessed($chosen); # only return if it was an object or name lookup worked
230
231         # FIXME
232         # die "no such backend"?
233         # currently, we fall back to default
234     }
235     
236     return $c->default_cache_backend;
237 }
238
239 sub choose_cache_backend { shift->NEXT::choose_cache_backend( @_ ) } # a convenient fallback
240
241 sub cache_set {
242     my ( $c, $key, $value, @meta ) = @_;
243     $c->choose_cache_backend_wrapper( key =>  $key, value => $value, @meta )->set( $key, $value );
244 }
245
246 sub cache_get {
247     my ( $c, $key, @meta ) = @_;
248     $c->choose_cache_backend_wrapper( key => $key, @meta )->get( $key );
249 }
250
251 sub cache_remove {
252     my ( $c, $key, @meta ) = @_;
253     $c->choose_cache_backend_wrapper( key => $key, @meta )->remove( $key );
254 }
255
256 __PACKAGE__;
257
258 __END__
259
260 =pod
261
262 =head1 NAME
263
264 Catalyst::Plugin::Cache - Flexible caching support for Catalyst.
265
266 =head1 SYNOPSIS
267
268         use Catalyst qw/
269         Cache
270     /;
271
272     # configure a backend or use a store plugin 
273     __PACKAGE__->config->{cache}{backend} = {
274         class => "Cache::Bounded",
275         # ... params ...
276     };
277
278     # In a controller:
279
280     sub foo : Local {
281         my ( $self, $c, $id ) = @_;
282
283         my $cache = $c->cache;
284
285         my $result;
286
287         unless ( $result = $cache->get( $id ) ) {
288             # ... calculate result ...
289             $c->cache->set( $id, $result );
290         }
291     };
292
293 =head1 DESCRIPTION
294
295 This plugin gives you access to a variety of systems for caching
296 data. It allows you to use a very simple configuration API, while
297 maintaining the possibility of flexibility when you need it later.
298
299 Among its features are support for multiple backends, segmentation based
300 on component or controller, keyspace partitioning, and so more, in
301 various subsidiary plugins.
302
303 =head1 METHODS
304
305 =over 4
306
307 =item cache $profile_name
308
309 =item cache %meta
310
311 Return a curried object with metadata from C<$profile_name> or as
312 explicitly specified.
313
314 If a profile by the name C<$profile_name> doesn't exist, but a backend
315 object by that name does exist, the backend will be returned instead,
316 since the interface for curried caches and backends is almost identical.
317
318 This method can also be called without arguments, in which case is
319 treated as though the C<%meta> hash was empty.
320
321 See L</METADATA> for details.
322
323 =item curry_cache %meta
324
325 Return a L<Catalyst::Plugin::Cache::Curried> object, curried with C<%meta>.
326
327 See L</METADATA> for details.
328
329 =item cache_set $key, $value, %meta
330
331 =item cache_get $key, %meta
332
333 =item cache_remove $key, %meta
334
335 These cache operations will call L<choose_cache_backend> with %meta, and
336 then call C<set>, C<get>, or C<remove> on the resulting backend object.
337
338 =item choose_cache_backend %meta
339
340 Select a backend object. This should return undef if no specific backend
341 was selected - its caller will handle getting C<default_cache_backend>
342 on its own.
343
344 This method is typically used by plugins.
345
346 =item get_cache_backend $name
347
348 Get a backend object by name.
349
350 =item default_cache_backend
351
352 Return the default backend object.
353
354 =item temporary_cache_backend
355
356 When no default cache backend is configured this method might return a
357 backend known to work well with the current L<Catalyst::Engine>. This is
358 a stub.
359
360 =item 
361
362 =back
363
364 =head1 METADATA
365
366 =head2 Introduction
367
368 Whenever you set or retrieve a key you may specify additional metadata
369 that will be used to select a specific backend.
370
371 This metadata is very freeform, and the only key that has any meaning by
372 default is the C<backend> key which can be used to explicitly choose a backend
373 by name.
374
375 The C<choose_cache_backend> method can be overridden in order to
376 facilitate more intelligent backend selection. For example,
377 L<Catalyst::Plugin::Cache::Choose::KeyRegexes> overrides that method to
378 select a backend based on key regexes.
379
380 Another example is a L<Catalyst::Plugin::Cache::ControllerNamespacing>,
381 which wraps backends in objects that perform key mangling, in order to
382 keep caches namespaced per controller.
383
384 However, this is generally left as a hook for larger, more complex
385 applications. Most configurations should make due XXXX
386
387 The simplest way to dynamically select a backend is based on the
388 L</Cache Profiles> configuration.
389
390 =head2 Meta Data Keys
391
392 C<choose_cache_backend> is called with some default keys.
393
394 =over 4
395
396 =item key
397
398 Supplied by C<cache_get>, C<cache_set>, and C<cache_remove>.
399
400 =item value
401
402 Supplied by C<cache_set>.
403
404 =item caller
405
406 The package name of the innermost caller that doesn't match
407 C<qr/Plugin::Cache/>.
408
409 =item caller_frame
410
411 The entire C<caller($i)> frame of C<caller>.
412
413 =item component
414
415 The package name of the innermost caller who C<isa>
416 L<Catalyst::Component>.
417
418 =item component_frame
419
420 This entire C<caller($i)> frame of C<component>.
421
422 =item controller
423
424 The package name of the innermost caller who C<isa>
425 L<Catalyst::Controller>.
426
427 =item controller_frame
428
429 This entire C<caller($i)> frame of C<controller>.
430
431 =back
432
433 =head2 Metadata Currying
434
435 In order to avoid specifying C<%meta> over and over again you may call
436 C<cache> or C<curry_cache> with C<%meta> once, and get back a B<curried
437 cache object>. This object responds to the methods C<get>, C<set>, and
438 C<remove>, by appending its captured metadata and delegating them to
439 C<cache_get>, C<cache_set>, and C<cache_remove>.
440
441 This is simpler than it sounds.
442
443 Here is an example using currying:
444
445     my $cache = $c->cache( %meta ); # cache is curried
446
447     $cache->set( $key, $value );
448
449     $cache->get( $key );
450
451 And here is an example without using currying:
452
453     $c->cache_set( $key, $value, %meta );
454
455     $c->cache_get( $key, %meta );
456
457 See L<Catalyst::Plugin::Cache::Curried> for details.
458
459 =head1 CONFIGURATION
460
461     $c->config->{cache} = {
462         ...
463     };
464
465 All configuration parameters should be provided in a hash reference
466 under the C<cache> key in the C<config> hash.
467
468 =head2 Backend Configuration
469
470 Configuring backend objects is done by adding hash entries under the
471 C<backends> key in the main config.
472
473 A special case is that the hash key under the C<backend> (singular) key
474 of the main config is assumed to be the backend named C<default>.
475
476 =over 4
477
478 =item class
479
480 Instantiate a backend from a L<Cache> compatible class. E.g.
481
482     $c->config->{cache}{backends}{small_things} = {
483         class    => "Cache::Bounded",
484         interval => 1000,
485         size     => 10000,
486     };
487     
488     $c->config->{cache}{backends}{large_things} = {
489         class => "Cache::Memcached::Managed",
490         data  => '1.2.3.4:1234',
491     };
492
493 The options in the hash are passed to the class's C<new> method.
494
495 The class will be C<required> as necessary during setup time.
496
497 =item store
498
499 Instantiate a backend using a store plugin, e.g.
500
501     $c->config->{cache}{backend} = {
502         store => "FastMmap",
503     };
504
505 Store plugins typically require less configuration because they are
506 specialized for L<Catalyst> applications. For example
507 L<Catalyst::Plugin::Cache::Store::FastMmap> will specify a default
508 C<share_file>, and additionally use a subclass of L<Cache::FastMmap>
509 that can also store non reference data.
510
511 The store plugin must be loaded.
512
513 =back
514
515 =head2 Cache Profiles
516
517 =over 4
518
519 =item profiles
520
521 Supply your own predefined profiles for cache metadata, when using the
522 C<cache> method.
523
524 For example when you specify
525
526     $c->config->{cache}{profiles}{thumbnails} = {
527         backend => "large_things",
528     };
529
530 And then get a cache object like this:
531
532     $c->cache("thumbnails");
533
534 It is the same as if you had done:
535
536     $c->cache( backend => "large_things" );
537
538 =back
539
540 =head2 Miscellaneous Configuration
541
542 =over 4
543
544 =item default_store
545
546 When you do not specify a C<store> parameter in the backend
547 configuration this one will be used instead. This configuration
548 parameter is not necessary if only one store plugin is loaded.
549
550 =back
551
552 =head1 TERMINOLOGY
553
554 =over 4
555
556 =item backend
557
558 An object that responds to the methods detailed in
559 L<Catalyst::Plugin::Cache::Backend> (or more).
560
561 =item store
562
563 A plugin that provides backends of a certain type. This is a bit like a
564 factory.
565
566 =item cache
567
568 Stored key/value pairs of data for easy re-access.
569
570 =item metadata
571
572 "Extra" information about the item being stored, which can be used to
573 locate an appropriate backend.
574
575 =item curried cache
576
577   my $cache = $c->cache(type => 'thumbnails');
578   $cache->set('pic01', $thumbnaildata);
579
580 A cache which has been pre-configured with a particular set of
581 namespacing data. In the example the cache returned could be one
582 specifically tuned for storing thumbnails.
583
584 An object that responds to C<get>, C<set>, and C<remove>, and will
585 automatically add metadata to calls to C<< $c->cache_get >>, etc.
586
587 =back
588
589 =head1 SEE ALSO
590
591 L<Cache> - the generic cache API on CPAN.
592
593 L<Catalyst::Plugin::Cache::Store> - how to write a store plugin.
594
595 L<Catalyst::Plugin::Cache::Curried> - the interface for curried caches.
596
597 L<Catalyst::Plugin::Cache::Choose::KeyRegexes> - choose a backend based on
598 regex matching on the keys. Can be used to partition the keyspace.
599
600 L<Catalyst::Plugin::Cache::ControllerNamespacing> - wrap backend objects in a
601 name mangler so that every controller gets its own keyspace.
602
603 =cut
604
605