HTML-Mason

 view release on metacpan or  search on metacpan

lib/HTML/Mason/Devel.pod  view on Meta::CPAN

arbitrary complex list or hash reference:

    $m->cache->set(name => $string);
    $m->cache->set(friends => \@list);
    $m->cache->set(map => \%hash);

You can fetch all the keys in a cache with

    my @idents = $m->cache->get_keys;

It should be noted that Mason reserves all keys beginning with
C<__mason> for its own use.

=head2 Expiration

You can pass an optional third argument to C<< $m->cache->set >>
indicating when the item should expire:

    $m->cache->set('name1', $string1, '5 min');  # Expire in 5 minutes
    $m->cache->set('name2', $string2, '3h');     # Expire in 3 hours

To change the expiration time for a piece of data, call C<set> again
with the new expiration. To expire an item immediately, use
C<< $m->cache->remove >>.

You can also specify an expiration condition when you fetch the item,
using the I<expire_if> option:

    my $result = $m->cache->get('key',
        expire_if=>sub { $_[0]->get_created_at < (stat($file))[9] });

I<expire_if> takes an anonymous subroutine, which is called with the
L<cache object|"Cache Object"> as its only parameter. If the
subroutine returns a true value, the item is expired. In the example
above, we expire the item whenever a certain file changes.

Finally, you can expire a cache item from an external script; see
L<Accessing a Cache Externally|"Accessing a Cache Externally"> below.

=head2 Avoiding Concurrent Recomputation

The code shown in "Basic Usage" above,

   my $result = $m->cache->get('key');
   if (!defined($result)) {
       ... compute $result ...
       $m->cache->set('key', $result);
   }

can suffer from a kind of race condition for caches that
are accessed frequently and take a long time to recompute.

Suppose that a particular cache value is accessed five times a
second and takes three seconds to recompute.  When the cache expires,
the first process comes in, sees that it is expired, and starts to
recompute the value.  The second process comes in and does the same thing.
This sequence continues until the first process finishes and stores
the new value.  On average, the value will be recomputed and written
to the cache 15 times!

One solution is the I<busy_lock> flag:

   my $result = $m->cache->get('key', busy_lock=>'30 sec');

In this case, when the value cannot be retrieved, C<get()> sets
the expiration time of the value 30 seconds in the future before
returning C<undef>.  This tells the first process to compute the new
value while causing subsequent processes to use the old value for 30
seconds. 

Should the 30 seconds expire before the first process is done, a second
process will start computing the new value while setting the expiration
time yet another 30 seconds in the future, and so on.

The disadvantage of this solution is that multiple writes to the cache
will be performed for each C<set()>.

Another solution, available only if you are using C<CHI>, is
C<expires_variance> which will create a variable time window during
which expiration may occur. See the C<CHI> documentation for details.

=head2 Caching All Output

Occasionally you will need to cache the complete output of a
component.  For this purpose, Mason offers the C<< $m->cache_self >>
method.  This method causes Mason to check to see if this component
has already been run and its output cached.  If this is the case, this
output is simply sent as output.  Otherwise, the component run
normally and its output and return value cached.

It is typically used right at the top of an C<< <%init> >> section:

    <%init>
    return if $m->cache_self(key => 'fookey', expires_in => '3 hours',
                             ... <other cache options> ...);
     ... <rest of init> ...
    </%init>

A full list of parameters and examples are available in the
L<cache_self|HTML::Mason::Request/item_cache_self> section of the Request
manual.

=head2 Cache Object

C<< $m->cache->get_object >> returns a C<Cache::Object> or
C<CHI::CacheObject> associated with a particular key. You can use this
to retrieve useful meta-data:

    my $co = $m->cache->get_object('name1');
    $co->get_created_at();    # when was object stored in cache
    $co->get_expires_at();    # when does object expire

=head2 Choosing a Cache Subclass - with Cache::Cache

The C<Cache::Cache> API is implemented by a variety of backend subclasses. For
example, C<FileCache> implements the interface with a set of
directories and files, C<MemoryCache> implements the interface in
process memory, and C<SharedMemoryCache> implements the interface in
shared memory.

By default C<< $m->cache >> uses C<FileCache>, but you can override
this with the I<cache_class> keyword. The value must be the name of a
C<Cache::Cache> subclass; the prefix "Cache::" need not be included.



( run in 0.846 second using v1.01-cache-2.11-cpan-39bf76dae61 )