File-DataClass
view release on metacpan or search on metacpan
lib/File/DataClass/Cache.pm view on Meta::CPAN
package File::DataClass::Cache;
use 5.01;
use namespace::autoclean;
use File::DataClass::Constants qw( FALSE NUL SPC TRUE );
use File::DataClass::Functions qw( merge_attributes throw );
use File::DataClass::Types qw( Bool Cache ClassName HashRef
LoadableClass Object Str );
use Storable qw( freeze );
use Try::Tiny;
use Moo;
# Public attributes
has 'cache' => is => 'lazy', isa => Object, builder => sub {
$_[ 0 ]->cache_class->new( %{ $_[ 0 ]->cache_attributes } ) };
has 'cache_attributes' => is => 'ro', isa => HashRef, required => TRUE;
has 'cache_class' => is => 'lazy', isa => LoadableClass,
default => 'Cache::FastMmap';
has 'log' => is => 'ro', isa => Object, required => TRUE;
# Private attributes
has '_mtimes_key' => is => 'ro', isa => Str, default => '_mtimes';
# Construction
around 'BUILDARGS' => sub {
my ($orig, $class, @args) = @_; my $attr = $orig->( $class, @args );
$attr->{cache_attributes} //= {}; my $cache_class;
$cache_class = delete $attr->{cache_attributes}->{cache_class}
and $attr->{cache_class} = $cache_class;
my $builder = delete $attr->{builder} or return $attr;
merge_attributes $attr, $builder, [ 'log' ];
return $attr;
};
# Private methods
my $_get_key_and_newest = sub {
my ($self, $paths) = @_; my $newest = 0; my $is_valid = TRUE; my $key;
for my $path (grep { defined && length "${_}" } @{ $paths }) {
my $mtime = $self->get_mtime( "${path}" ) or $is_valid = FALSE;
($mtime and $path->exists and $mtime == $path->stat->{mtime})
or $is_valid = FALSE;
$mtime and $mtime > $newest and $newest = $mtime;
$key .= $key ? "~${path}" : "${path}";
}
return ($key, $is_valid ? $newest : undef);
};
# Public methods
sub get {
my ($self, $key) = @_; $key .= NUL;
my $cached = $key ? $self->cache->get( $key ) : FALSE;
$cached and return ($cached->{data}, $cached->{meta});
return (undef, { mtime => undef });
}
sub get_by_paths {
my ($self, $paths) = @_;
my ($key, $newest) = $self->$_get_key_and_newest( $paths );
return ($self->get( $key ), $newest);
}
sub get_mtime {
lib/File/DataClass/Cache.pm view on Meta::CPAN
my ($self, $key, $data, $meta) = @_; $meta //= { mtime => undef };
my $val = { data => $data, meta => $meta };
try {
$key eq $self->_mtimes_key and throw 'key not allowed';
$self->cache->set( $key, $val ) or throw 'set operation returned false';
$self->set_mtime( $key, $meta->{mtime} );
}
catch {
my $len = length( $key ) + length( freeze $val );
$self->log->error( "Cache key ${key}(${len}) set failed: ${_}" );
};
return ($data, $meta);
}
sub set_by_paths {
my ($self, $paths, $data, $meta) = @_;
my ($key, $newest) = $self->$_get_key_and_newest( $paths );
$meta->{mtime} = $newest;
return $self->set( $key, $data, $meta );
}
sub set_mtime {
my ($self, $k, $v) = @_;
return $self->cache->get_and_set( $self->_mtimes_key, sub {
my (undef, $mtimes) = @_;
if (defined $v) { $mtimes->{ $k } = $v } else { delete $mtimes->{ $k } }
return $mtimes;
} );
}
1;
__END__
=pod
=head1 Name
File::DataClass::Cache - Accessors and mutators for the cache object
=head1 Synopsis
package File::DataClass::Schema;
use Moo;
use File::DataClass::Types qw(Cache);
use File::DataClass::Cache;
has 'cache' => is => 'lazy', isa => Cache;
has 'cache_attributes' => is => 'ro', isa => 'HashRef',
default => sub { return {} };
my $_cache_objects = {};
sub _build_cache {
my $self = shift; (my $ns = lc __PACKAGE__) =~ s{ :: }{-}gmx; my $cache;
my $attrs = { cache_attributes => { %{ $self->cache_attributes } },
builder => $self };
$ns = $attrs->{cache_attributes}->{namespace} ||= $ns;
exists $_cache_objects->{ $ns } and return $_cache_objects->{ $ns };
$self->cache_class eq 'none' and return Class::Null->new;
$attrs->{cache_attributes}->{share_file}
||= NUL.$self->tempdir->catfile( "${ns}.dat" );
return $_cache_objects->{ $ns } = $self->cache_class->new( $attrs );
}
=head1 Description
Adds meta data and compound keys to the L<CHI> caching API. In instance of
this class is created by L<File::DataClass::Schema>
=head1 Configuration and Environment
The class defines these attributes
=over 3
=item C<cache>
An instance of the L<CHI> cache object
=item C<cache_attributes>
A hash ref passed to the L<CHI> constructor
=item C<cache_class>
The class name of the cache object, defaults to L<CHI>
=item C<log>
Log object which defaults to L<Class::Null>
=back
=head1 Subroutines/Methods
=head2 BUILDARGS
Constructs the attribute hash passed to the constructor method.
=head2 get
($data, $meta) = $schema->cache->get( $key );
Returns the data and metadata associated with the given key. If no cache
entry exists the data returned is C<undef> and the metadata is a hash ref
( run in 1.292 second using v1.01-cache-2.11-cpan-5a3173703d6 )