File Coverage

blib/lib/Hook/Modular/Cache.pm
Criterion Covered Total %
statement 31 60 51.6
branch 4 22 18.1
condition 4 15 26.6
subroutine 9 14 64.2
pod 6 6 100.0
total 54 117 46.1


line stmt bran cond sub pod time code
1 10     10   190 use 5.008;
  10         58  
  10         453  
2 10     10   55 use strict;
  10         19  
  10         296  
3 10     10   55 use warnings;
  10         20  
  10         621  
4              
5             package Hook::Modular::Cache;
6             BEGIN {
7 10     10   203 $Hook::Modular::Cache::VERSION = '1.101050';
8             }
9             # ABSTRACT: Cache for Hook::Modular
10 10     10   62 use File::Path;
  10         79  
  10         659  
11 10     10   55 use File::Spec;
  10         25  
  10         134  
12 10     10   344 use UNIVERSAL::require;
  10         15  
  10         87  
13              
14             sub new {
15 12     12 1 39 my ($class, $conf) = @_;
16 12 50 33     570 mkdir $conf->{base}, 0700 unless -e $conf->{base} && -d_;
17              
18             # Cache default configuration
19 12   50     86 $conf->{class} ||= 'Cache::FileCache';
20 12   50     472 $conf->{params} ||= {
      50        
21             cache_root => File::Spec->catfile($conf->{base}, 'cache'),
22             default_expires_in => $conf->{expires} || 'never',
23             directory_umask => 0077,
24             };
25 12         326 $conf->{class}->require;
26              
27             # If class is not loadable, falls back to on memory cache
28 12 50       191 if ($@) {
29 12         97 Hook::Modular->context->log(error =>
30             "Can't load $conf->{class}. Falling back to Hook::Modular::Cache::Null"
31             );
32 12         7867 require Hook::Modular::Cache::Null;
33 12         50 $conf->{class} = 'Hook::Modular::Cache::Null';
34             }
35 12 50       210 my $self = bless {
36             base => $conf->{base},
37             cache => $conf->{class}->new($conf->{params}),
38             to_purge => $conf->{expires} ? 1 : 0,
39             }, $class;
40             }
41              
42             sub path_to {
43 0     0 1 0 my ($self, @path) = @_;
44 0 0       0 if (@path > 1) {
45 0         0 my @chunk = @path[ 0 .. $#path - 1 ];
46 0         0 mkpath(File::Spec->catfile($self->{base}, @chunk), 0, 0700);
47             }
48 0         0 File::Spec->catfile($self->{base}, @path);
49             }
50              
51             sub get {
52 0     0 1 0 my $self = shift;
53 0         0 my $value;
54 0 0       0 if ($self->{cache}->isa('Cache')) {
55 0         0 eval { $value = $self->{cache}->thaw(@_) };
  0         0  
56 0 0 0     0 if ($@ && $@ =~ /Storable binary/) {
57 0         0 $value = $self->{cache}->get(@_);
58             }
59             } else {
60 0         0 $value = $self->{cache}->get(@_);
61             }
62 0 0       0 my $hit_miss = defined $value ? "HIT" : "MISS";
63 0         0 Hook::Modular->context->log(debug => "Cache $hit_miss: $_[0]");
64 0         0 $value;
65             }
66              
67             sub get_callback {
68 0     0 1 0 my ($self, $key, $callback, $expiry) = @_;
69 0         0 my $data = $self->get($key);
70 0 0       0 if (defined $data) {
71 0         0 return $data;
72             }
73 0         0 $data = $callback->();
74 0 0       0 if (defined $data) {
75 0         0 $self->set($key => $data, $expiry);
76             }
77 0         0 $data;
78             }
79              
80             sub set {
81 0     0 1 0 my ($self, $value) = @_[0,2];
82 0 0 0     0 my $setter = $self->{cache}->isa('Cache') && ref $value ? 'freeze' : 'set';
83 0         0 $self->{cache}->$setter(@_);
84             }
85              
86             sub remove {
87 0     0 1 0 my $self = shift;
88 0         0 $self->{cache}->remove(@_);
89             }
90              
91             sub DESTROY {
92 2     2   43 my $self = shift;
93 2 50       48 $self->{cache}->purge if $self->{to_purge};
94             }
95             1;
96              
97              
98             __END__