* "Jason A. Crome" <[EMAIL PROTECTED]> [2006-07-12T21:13:24]
> $self->cache->config({
>   driver     => 'CacheFastMmap',
>   share_file => '/home/webapp/cache/mmapcache',
>   cache_size => '1m',
> });

How about add_cache?  You could alias add_caches and add a default_cache
method.  Failing that, I'd suggest:

  $self->cache->config({
    default => 'abacus',
    caches  => [
      { name => ..., ...},
      { .. },
    ],
  });

> # The cache in action!
> $self->cache->set( $key, $value );

If you replace that comma with a fat arrow in your example, people will
understand twice as fast.

> "CGI::Application::Plugin::Cache" is dependent on one or more  
> drivers to provide functionality from various caching backends.

I would suggest that CAP::Cache is, itself, a driver.  A driver can:

  get
  set
  remove
  purge_expired
  config

config is different per driver, as is the implementation of set/get/remove/etc.

CAP::Cache itself is just CAP::Cache::Driver::Multiplex, which multiplexes for
other drivers.  You could, in fact, do this:

  cache::multiplex --+-- cache::multiplex --+-- cache::disk
                     |                      |
                     |                      +-- cache::memory
                     |
                     +-- cache::multiplex --+-- cache::memory (2nd instance)
                     |                      |
                     |                      +-- cache::mysql
                     +-- cache::make_shit_up

Why?  Well, maybe those second-level multiplexers are subclasses that do
something like log, or determine order based on load, or something else.

What makes the "top level" cache different from any other one, apart from the
fact that it implements caching as muxing over other caches?

Consider: http://search.cpan.org/dist/Bryar-DataSource-Multiplex

Simple example of "an X that multiplexes other Xes and servers as a good top
level."

>     Named caches, while handy, add a great deal of complexity to your
>     application. As such, developers need to understand how
>     "CGI::Application::Plugin::Cache" deals with named caches.

...and heck, you can have the plugin part of CAP instantiate the proper kind of
cache based on its first config.  If you give it one cache, you get that.  If
you give many, you get the multiplexer.  Or you write into the base class the
ability for any driver to promote to the multiplexer... maybe.  That might be
YAGNI fodder.

>         $self->cache( 'memory', 'disk' )->set( "mykey", "thisvalue" );

These could be args to the multiplexer's set/get.

  $self->cache->set(mykey => $value, { caches => [ qw(memory disk) ] );

This has the readability advantage of having arguments at only one stage in the
method chain, and helps keep ->cache as "the thing that gives you your cache."

The problem is in ->get if you support references as keys.

  $self->cache->get('key1', 'key2', \%hash);

Is that final argument a key or extra args?  To allow that you might want to
say that "to pass extra args, you must pass the keys to get as an arrayref" --
but that's still ambiguous, because what if you're getting the entry for an
arrayref and the entry... I'm not sure.

I really do like the idea that ->cache just returns one object, taking no args.
Maybe references as keys will never matter, and this worry is moot.

> $self->cache()->set( $key, $value, [ $expiry, { %options } ]);
> $self->cache( 'memory' )->set( $key, $value, [ $expiry, { %options } ]);

Why not:

  set(%key_value_pairs)
  set(%key_value_pairs, \$expiry)
  set(%key_value_pairs, \%option)

Where the second is sugar for (%kvp, { expiry => $expiry, ... });

> my ($value) = $self->cache->get( $key );
> my ($value1, $value2, $value3) = $self->cache( 'network' )->get(
>   [ "key1", "key2", "key3" ]
> );

Why a scalar or an arrayref?  Does that mean that you are precluding references
as keys?  (This question goes for other methods, too.)



Finally, I'd suggest that there is absolutely nothing specific to CGI::App
here.  I could see using this in /any/ class, like this:

  use Crome::Cache slot => sub { \$_[0]->{__cache} };

...where the slot routine is used to build the cache method.  It returns a
coderef that is called on the object to find where the cache is kept.  In other
words, when you call $self->cache, the cache method finds the cache object by
calling the "slot" routine.  This lets you use this mixin with objects that use
nearly any form of implementation: inside-out, array, various hash types, etc.

-- 
rjbs

Attachment: signature.asc
Description: Digital signature

Reply via email to