File Coverage

blib/lib/Starch/Store/CHI.pm
Criterion Covered Total %
statement 32 32 100.0
branch 1 2 50.0
condition n/a
subroutine 10 10 100.0
pod 2 2 100.0
total 45 46 97.8


line stmt bran cond sub pod time code
1             package Starch::Store::CHI;
2              
3             $Starch::Store::CHI::VERSION = '0.04';
4              
5             =head1 NAME
6              
7             Starch::Store::CHI - Starch storage backend using CHI.
8              
9             =head1 SYNOPSIS
10              
11             my $starch = Starch->new(
12             store => {
13             class => '::CHI',
14             chi => {
15             driver => 'File',
16             root_dir => '/path/to/root',
17             },
18             },
19             ...,
20             );
21              
22             =head1 DESCRIPTION
23              
24             This L store uses L to set and get state data.
25              
26             =head1 EXCEPTIONS
27              
28             By default L will catch errors and log them using L
29             and keep on going as if nothing went wrong. In Starch, stores are
30             expected to loudly throw exceptions, so it is suggested that you
31             specify these arguments to your CHI driver:
32              
33             on_get_error => 'die',
34             on_set_error => 'die',
35              
36             And then, if you still want the errors logged, you can use
37             L. This is especially
38             important if you are using the L
39             plugin which will throw an exception when the timeout is exceeded
40             which then CHI will catch and log by default, which is not what
41             you want.
42              
43             =head1 PERFORMANCE
44              
45             When using CHI there are various choices you need to make:
46              
47             =over
48              
49             =item *
50              
51             Which backend to use? If data persistence is not an issue, or
52             you're using CHI as your outer store in L
53             then Memcached or Redis are common solutions which have high
54             performance.
55              
56             =item *
57              
58             Which serializer to use? Nowadays L is the serialization
59             performance heavyweight, with L coming up a close second.
60              
61             =item *
62              
63             Which driver to use? Some backends have more than one driver, and
64             some drivers perform better than others. The most common example of
65             this is Memcached which has three drivers which can be used with
66             CHI.
67              
68             =back
69              
70             Make sure you ask these questions when you implement CHI for
71             Starch, and take the time to answer them well. It can make a big
72             difference.
73              
74             =cut
75              
76 1     1   10777 use CHI;
  1         27478  
  1         32  
77 1     1   9 use Types::Standard -types;
  1         2  
  1         17  
78 1     1   3860 use Types::Common::String -types;
  1         2  
  1         8  
79 1     1   1175 use Scalar::Util qw( blessed );
  1         2  
  1         80  
80              
81 1     1   7 use Moo;
  1         2  
  1         10  
82 1     1   384 use strictures 2;
  1         7  
  1         36  
83 1     1   174 use namespace::clean;
  1         1  
  1         8  
84              
85             with qw(
86             Starch::Store
87             );
88              
89             after BUILD => sub{
90             my ($self) = @_;
91              
92             # Get this loaded as early as possible.
93             $self->chi();
94              
95             return;
96             };
97              
98             =head1 REQUIRED ARGUMENTS
99              
100             =head2 chi
101              
102             This must be set to either hash ref arguments for L or a
103             pre-built CHI object (often retrieved using a method proxy).
104              
105             When configuring Starch from static configuration files using a
106             L
107             is a good way to link your existing L object constructor
108             in with Starch so that starch doesn't build its own.
109              
110             =cut
111              
112             has _chi_arg => (
113             is => 'ro',
114             isa => (InstanceOf[ 'CHI::Driver' ]) | HashRef,
115             init_arg => 'chi',
116             required => 1,
117             );
118              
119             has chi => (
120             is => 'lazy',
121             isa => InstanceOf[ 'CHI::Driver' ],
122             init_arg => undef,
123             );
124             sub _build_chi {
125 5     5   44 my ($self) = @_;
126              
127 5         14 my $chi = $self->_chi_arg();
128 5 50       17 return $chi if blessed $chi;
129              
130 5         44 return CHI->new( %$chi );
131             }
132              
133             =head1 METHODS
134              
135             =head2 set
136              
137             Set L.
138              
139             =head2 get
140              
141             Set L.
142              
143             =head2 remove
144              
145             Set L.
146              
147             =cut
148              
149             sub set {
150             my ($self, $id, $namespace, $data, $expires) = @_;
151              
152             local $Carp::Interal{ (__PACKAGE__) } = 1;
153              
154             $self->chi->set(
155             $self->stringify_key( $id, $namespace ),
156             $data,
157             $expires ? ($expires) : (),
158             );
159              
160             return;
161             }
162              
163             sub get {
164 19     19 1 11773 my ($self, $id, $namespace) = @_;
165              
166 19         38 local $Carp::Interal{ (__PACKAGE__) } = 1;
167              
168 19         267 return $self->chi->get(
169             $self->stringify_key( $id, $namespace ),
170             );
171             }
172              
173             sub remove {
174 6     6 1 3393 my ($self, $id, $namespace) = @_;
175              
176 6         14 local $Carp::Interal{ (__PACKAGE__) } = 1;
177              
178 6         92 $self->chi->remove(
179             $self->stringify_key( $id, $namespace ),
180             );
181              
182 6         597 return;
183             }
184              
185             1;
186             __END__