Memoize-Memcached-Attribute
view release on metacpan or search on metacpan
lib/Memoize/Memcached/Attribute.pm view on Meta::CPAN
if ($@) {
require Cache::Memcached;
$memcache_pkg = 'Cache::Memcached';
}
return $memcache_pkg->new(\%CLIENT_PARAMS);
}
sub CacheMemoize :ATTR_SUB {
my ($package, $symbol, $referent, $attr, $params) = @_;
no strict 'refs';
$params = _parse_attr_params($params);
my $is_method = 0;
if (@$params > 1) {
my $type = shift @$params;
$is_method = 1 if (lc($type) eq 'method');
}
my $duration = $params->[0];
my $symbol_name = join('::', $package, *{ $symbol }{NAME});
no warnings 'redefine';
my $original = \&{ $symbol_name };
*{$symbol_name} = sub {
my @args = @_;
# if we're in a method, don't use the object to build the key
my @key_args = @args;
shift @key_args if ($is_method);
my $key = _build_key($symbol_name, @key_args);
if (wantarray) {
$key .= '-wantarray';
my $ref = $MEMCACHE->get($key) || do {
my @list = $original->(@args);
$MEMCACHE->set($key, \@list, $duration) if (@list);
\@list;
};
return @$ref;
}
my $cached = $MEMCACHE->get($key);
return $cached if (defined $cached);
my $result = $original->(@args);
$MEMCACHE->set($key, $result, $duration) if (defined $result);
return $result;
};
}
sub invalidate {
my $symbol_name = shift;
if ($symbol_name !~ /::/) {
# build the full method from the caller's namespace if necessary
$symbol_name = join('::', (caller)[0], $symbol_name);
}
my $key = Memoize::Memcached::Attribute::_build_key($symbol_name, @_);
$MEMCACHE->delete($key);
$MEMCACHE->delete("${key}-wantarray");
}
sub _parse_attr_params {
my ($string) = @_;
return [] unless defined $string;
my $data = eval "
no warnings;
no strict;
[$string]
";
return $data || [$string];
}
sub _build_key {
local $Storable::canonical = 1;
return Digest::MD5::md5_base64(Storable::nfreeze(\@_));
}
1;
=pod
=head1 NAME
Memoize::Memcached::Attribute - auto-memoize function results using memcached and subroutine attributes
=head1 VERSION
version 0.11
=head1 SYNOPSIS
If you're running memcache on your local box, with the default port, you can initialize without passing any
parameters:
use Memoize::Memcached::Attribute;
This will use the default server list of 127.0.0.1:11211
If you want to specify the constructor parameters for your Cache::Memcached or Cache::Memcached::Fast client object,
you can pass them in during import:
use Memoize::Memcached::Attribute (
servers => [ '192.168.1.2:11211', '192.168.1.3:11211' ],
_connect_timeout => 0.1,
max_failures => 5,
);
Alternatively, you can pass in your memcache client object entirely (we use this because
we subclass Cache::Memcached::Fast to add some additional methods and default parameters):
( run in 3.086 seconds using v1.01-cache-2.11-cpan-a49fcb8fa48 )