Hello all,

Please see the attached RFC. I know a caching plugin has been discussed in the past, but recent needs at work (and recent conversations with Cees) have motivated me to produce this. When you have an opportunity, please read and give me your feedback.

One thing I have considered adding but have not done so yet is cache rollover. To explain this a bit... If you look for a parameter in an unspecified cache, and the parameter doesn't exist there, you search all caches for a match on that parameter. Which begs the question, what should a set operation do? Set in one cache or all caches? What are your thoughts on this?

Thanks in advance for your feedback,
Jason

NAME
    CGI::Application::Plugin::Cache - Generic caching framework for
    CGI::Application.

VERSION
    Version 0.01

SYNOPSIS
        use CGI::Application;
        use CGI::Application::Plugin::Cache;

        # Configure the cache.  Do this in setup() or cgiapp_init().
        $self->cache->config(
            DRIVER => [ 'CacheFastMmap',
                share_file => '/home/webapp/cache/mmapcache',
                cache_size => '1m',
            ],
        );

        # Or, create named caches. . .
        $self->cache( 'memory' )->config(
            DRIVER => [ 'CacheFastMmap',
                share_file => '/home/webapp/cache/mmapcache',
                cache_size => '1m',
            ],
        );

        $self->cache( 'disk' )->config(
            DRIVER => [ 'CacheFileCache',
                namespace  => 'Default',
                cache_root => '/home/webapp/cache/filecache',
            ],
        );

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

        my $value  = $self->cache->get( $key );
my %values = $self->cache( 'memcached' )->get([ "key1", "key2", "key3" ]);

        my $count = $self->cache->remove( $key );
my $count = $self->cache( 'disk' )->remove([ "key1", "key2", "key3" ]);

        my $count = $self->cache->purge;
        my $count = $self->cache( 'memory' )->purge;

        $self->cache->clear;
        $self->cache( 'memcached' )->clear;

$self->cache->object->some_cache_object_method( $arg1, $arg2, ...); $self->cache( 'disk' )->object->some_cache_object_method ( $arg1, $arg2, ...);

DESCRIPTION
CGI::Application::Plugin::Cache provides a generic caching interface for CGI::Application-derived web applications. A single method, "cache", gives the developer complete control over defining and using a cache in
    their application.

CGI::Application::Plugin::Cache is dependent on one or more drivers to
    provide functionality from various caching backends.
CGI::Application::Plugin::Cache comes with drivers for the Cache::Cache
    suite of caching modules, Cache::FastMmap, Cache::Memcached, and
Tie::Cache::LRU. For information about writing your own drivers, see
    CGI::Application::Plugin::Cache::Driver.

  Named Caches
You may wish to provide one or more data caches to your application, and you may wish to store those caches in different types of storage medium
    (disk, memory, shared memory, network cache, etc.).
    CGI::Application::Plugin::Cache makes it easy to provide this
    functionality in your applications through the use of named caches:

        $self->cache( 'memory' )->config(
            DRIVER => [ 'CacheFastMmap',
                share_file => '/home/webapp/cache/mmapcache',
                cache_size => '1m',
            ],
        );

        $self->cache( 'disk' )->config(
            DRIVER => [ 'CacheFileCache',
                namespace  => 'Default',
                cache_root => '/home/webapp/cache/filecache',
            ],
        );

        $self->cache( 'memory' )->set( "yourkey", "yourvalue" );
        my $value = $self->cache( 'disk' )->get( "mykey" );

MOTIVATIONS
It was originally my intent to create a simple caching plugin based upon Cache::Cache. My need was very simple: I had a drop-down list of items that was populated from the database on every request to a particular page. The data in those lists changed once or twice a year. Because of the static nature of this data, it became a great candidate for caching.
    The performance benefits were obvious to me.

Some issues with Cache::Cache were pointed out to me, particularly the (lack of) efficency when it came to determining the expiration time of a value and purging those expired values. Cache::FastMmap was recommended to me as a great alternative. Unfortunately, Cache::FastMmap doesn't play nicely with Windows, which is what half of our web applications run on. Wanting to implement caching throughout our suite of applications, but not wanting to write custom caching code for each platform we deploy
    to, drove me to creating a generic, reusable caching interface.

EXPORTED METHODS
  cache()
Everything in CGI::Application::Plugin::Cache is controlled through this
    method. "cache()" returns a CGI::Application::Plugin::Cache object
unless it was called as a class method, in which case it returns the
    name of the class.

When using the cache, always invoke this method in one of the following
    two ways:

        $self->cache->method_to_invoke( @args );

        - or -

        __PACKAGE__->cache->method_to_invoke (@args );

When using multiple caches, you may provide the name of the cache to use as an argument to "cache()". If a cache is not explicitly specified, we use the last cache that was used. If a cache was never specified, we use the first cache that was defined. This is the same rationale used by
    CGI::Application::Plugin::DBH.

METHODS
  config()
# Simple configuration when implementing a single caching mechanism
        # in your application.
        $self->cache->config(
            DRIVER => [ 'CacheFastMmap',
                share_file => '/home/webapp/cache/mmapcache',
                cache_size => '1m',
            ],
        );

# Using a named configurations to distinguish these from the above
        # configuration.
        $self->cache( 'disk' )->config(
            DRIVER => [ 'CacheFileCache',
                namespace  => 'Default',
                cache_root => '/home/webapp/cache/filecache',
            ],
        );

        $self->cache( 'memory' )->config(
            DRIVER => [ 'CacheFastMmap',
                share_file => '/home/webapp/cache/mmapcache',
                cache_size => '1m',
            ],
        );

        $self->cache( 'memcached' )->config(
            DRIVER => [ 'CacheMemcached',
servers => [ '192.168.0.10:11211', '192.168.0.20:11211' ],
                debug     => 0,
                namespace => 'myapp',
            ],
        );

Configures the caching module. It can be called as an object method or a
    class method.

"config()" takes a single argument: "DRIVER". It specifies which of the caching drivers you wish to use for this particular cache. For sake of simplicity, you can omit CGI::Application::Plugin::Cache::Driver:: when
    specifying which driver to use. If the underlying caching module
requires additional configuration parameters, you may pass "config()" an
    array reference that contains the name of the driver as its first
    parameter and the required options as the rest of the array.

"config()" should be called in either your applications "cgiapp_init()"
    or "setup()" events.

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

Sets the specified key to the value provided in the specified cache. If no cache was specified, the key/value combination is added to the last
    active cache.

Note: not all caching backends support parameter-level expiration. In
    particular, Cache::FastMmap does not provide the ability to expire
different parameters at different times. This functionality may, at some
    point in the future, be added to drivers for backends that do not
    provide that functionality.

Any options specified in %options are passed directly to the underlying
    caching mechanism.

  get()
        my $value  = $self->cache->get( $key );
my %values = $self->cache( 'memcached' )->get([ "key1", "key2", "key3" ]);

Retrieves the value associated with $key from the specified cache. If a cache is not specified, $key is retrieved from the last active cache.

If a list of keys are provided, "get()" returns a hash containing the
    list of keys and their associated values.

    If a key is not found, "get()" returns "undef".

  remove()
        my $count = $self->cache->remove( $key );
my $count = $self->cache( 'disk' )->remove([ "key1", "key2", "key3" ]);

    Removes the specified key(s) (and the associated values) from the
specified cache. If a cache was not specified, the key/value combination
    is removed from the last active cache.

  purge()
        my $count = $self->cache->purge;
        my $count = $self->cache( 'memory' )->purge;

Removes all expired objects from the specified cache. If no cache is
    specified, all expired items are purged from the last active cache.
    Returns the number of items that were removed from the cache.

  clear()
        $self->cache->clear;
        $self->cache( 'memcached' )->clear;

Removes all objects from the specified cache. If no cache was specified,
    all objects are removed from the last active cache.

  object()
$self->cache->object->some_cache_object_method( $arg1, $arg2, ...); $self->cache( 'disk' )->object->some_cache_object_method ( $arg1, $arg2, ...);

Provides direct access to the underlying caching object. This method *should* only be rarely used - i.e., for circumstances where there is some functionality provided by the underlying caching mechanism that is
    not supported by the standard driver interface. Using "object()"
    bypasses many of the benefits provided by
CGI::Application::Plugin::Cache, and as such, it's regular use is not
    endorsed.

BUGS
    Please report any bugs or feature requests to
    "[EMAIL PROTECTED]", or through the web
    interface at
<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=CGI-Application- Plugin-C ache>. I will be notified, and then you'll automatically be notified of
    progress on your bug as I make changes.

ACKNOWLEDGEMENTS
A big thanks to Cees Hek for helping me transform my idea for a simple Cache::Cache plugin to a fully-featured generic caching interface. And,
    as always, thanks to the usual crowd in #cgiapp on irc.perl.org for
    keeping me company and making these projects worthwhile.

SEE ALSO
    CGI::Application, Cache::Cache, Cache::FastMmap, Cache::Memcached.

AUTHOR
    Jason A. Crome, "<[EMAIL PROTECTED]>"

COPYRIGHT & LICENSE
    Copyright 2006 Jason A. Crome, all rights reserved.

This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.


---------------------------------------------------------------------
Web Archive:  http://www.mail-archive.com/[email protected]/
             http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to