File Coverage

blib/lib/Redis/ScriptCache.pm
Criterion Covered Total %
statement 18 74 24.3
branch 0 24 0.0
condition 0 5 0.0
subroutine 6 14 42.8
pod 7 7 100.0
total 31 124 25.0


line stmt bran cond sub pod time code
1             package Redis::ScriptCache;
2 1     1   37123 use strict;
  1         1  
  1         23  
3 1     1   8 use warnings;
  1         1  
  1         44  
4              
5             our $VERSION = '0.03';
6              
7 1     1   5 use File::Basename;
  1         5  
  1         111  
8 1         18 use File::Spec qw(
9             catdir
10             splitdir
11 1     1   10 );
  1         5  
12 1     1   4 use Carp;
  1         1  
  1         82  
13              
14             use Class::XSAccessor {
15 1         18 getters => [qw(
16             redis_conn
17             script_dir
18             _script_cache
19             )],
20 1     1   669 };
  1         11481  
21              
22             sub new {
23 0     0 1   my $class = shift;
24 0           my $self = bless { @_ }, $class;
25              
26             # initialize the cache
27 0           $self->{_script_cache} = {};
28             # redis_conn is compulsory
29 0 0         $self->redis_conn
30             or croak('Need Redis connection');
31             # canonicalize script_dir
32 0           $self->_set_script_dir;
33              
34 0           return $self;
35             }
36              
37             sub _set_script_dir {
38 0     0     my( $self, $script_dir ) = @_;
39 0   0       my $script_dir_to_set = $script_dir // $self->script_dir // undef;
      0        
40 0 0         $self->{script_dir} = File::Spec->catdir( File::Spec->splitdir( $script_dir_to_set ) )
41             if $script_dir_to_set;
42 0           return $self;
43             }
44              
45             sub register_all_scripts {
46 0     0 1   my $self = shift;
47 0           my %args = @_;
48              
49             $self->_set_script_dir( $args{script_dir} )
50 0 0         if $args{script_dir};
51              
52 0 0         if ( $self->script_dir ) {
53 0           for my $file (glob($self->script_dir . '/*.lua')) {
54 0           $self->register_file(basename($file));
55             }
56 0           return $self->scripts;
57             } else {
58 0           croak('No script_dir specified');
59             }
60             }
61              
62             sub register_script {
63 0     0 1   my ($self, $script_name, $script) = @_;
64 0 0         my $script_ref = ref($script) ? $script : \$script;
65             return $script_name
66 0 0         if exists $self->{_script_cache}->{$script_name};
67              
68 0           my $sha;
69             eval {
70 0           $sha = $self->redis_conn->script_load($$script_ref);
71 0           1;
72 0 0         } or do {
73 0           croak("redis script_load failed: $@");
74             };
75 0           $self->{_script_cache}->{$script_name} = $sha;
76              
77 0           return $script_name;
78             }
79              
80             sub run_script {
81 0     0 1   my ($self, $script_name, $args) = @_;
82            
83 0           my $conn = $self->redis_conn;
84 0           my $sha = $self->_script_cache->{$script_name};
85              
86 0 0         croak("Unknown script $script_name") if !$sha;
87              
88 0           my $return;
89             eval {
90 0 0         $return = $conn->evalsha($sha, ($args ? (@$args) : (0)));
91 0           1;
92 0 0         } or do {
93 0           croak("redis evalsha failed: $@");
94             };
95              
96 0           return $return;
97             }
98              
99             sub register_file {
100 0     0 1   my ($self, $path_to_file) = @_;
101 0 0         open my $fh, '<', File::Spec->catdir( $self->script_dir, $path_to_file )
102             or croak "error opening $path_to_file: $!";
103              
104 0           my $script_name = basename( $path_to_file );
105 0           $script_name =~ s/\.lua$//;
106 0           my $script = do { local $/; <$fh> };
  0            
  0            
107 0           return $self->register_script($script_name, $script);
108             }
109              
110             sub scripts {
111 0     0 1   my ($self) = @_;
112 0           return keys %{ $self->_script_cache };
  0            
113             }
114              
115             sub flush_all_scripts {
116 0     0 1   my ($self) = @_;
117             eval {
118 0           $self->redis_conn->script_flush();
119 0           1;
120 0 0         } or do {
121 0           croak "redis script_flush failed: $@";
122             };
123 0           $self->{_script_cache} = {};
124 0           return $self;
125             }
126              
127             1;
128              
129             __END__