1CHI::Driver::DevelopmenUts(e3r)Contributed Perl DocumentCaHtIi:o:nDriver::Development(3)
2
3
4

NAME

6       CHI::Driver::Development - Manual for developing new CHI drivers
7

VERSION

9       version 0.61
10

SYNOPSIS

12           package CHI::Driver::MyDriver;
13           use Moo;
14           use strict;
15           use warnings;
16
17           extends 'CHI::Driver';
18
19           has ...;
20
21           sub fetch {
22               my ( $self, $key ) = @_;
23
24           }
25
26           sub store {
27               my ( $self, $key, $data[, $expires_in] ) = @_;
28
29           }
30
31           sub remove {
32               my ( $self, $key ) = @_;
33
34           }
35
36           sub clear {
37               my ($self) = @_;
38
39           }
40
41           sub get_keys {
42               my ($self) = @_;
43
44           }
45
46           sub get_namespaces {
47               my ($self) = @_;
48
49           }
50

DESCRIPTION

52       This document describes how to implement a new CHI driver.
53
54       The easiest way to start is to look at existing drivers, such as
55       CHI::Driver::Memory and CHI::Driver::FastMmap.
56

NAMING

58       If you are going to publicly release your driver, call it
59       'CHI::Driver::something' so that users can create it with
60
61           CHI->new(driver => 'I<something>');
62
63       If it's an internal driver, you can call it whatever you like and
64       create it like
65
66           CHI->new(driver => '+My::Internal::CHI::Driver');
67

MOO / MOOSE

69       CHI driver classes must be Moo or Moose based to be fully functional,
70       since we use Moose roles to implement various features. For backward
71       compatibility, non-Moo/Moose drivers will still work at a basic level,
72       but you will see an error if using any feature requiring a role.
73
74       All drivers must directly or indirectly extend CHI::Driver.
75

NAMESPACE

77       All cache handles have an assigned namespace that you can access with
78       "$self->namespace". You should use the namespace to partition your data
79       store. That is, two cache objects with different namespaces should be
80       able to access the same key without any collision.
81
82       Examples:
83
84       •   The Memory driver uses a separate sub-hash inside its main memory
85           hash for each namespace.
86
87       •   The File driver uses a separate top-level directory for each
88           namespace.
89
90       •   The FastMmap driver uses a separate Cache::FastMmap file for each
91           namespace.
92

METHODS

94   Required methods
95       The following methods have no default implementation, and MUST be
96       defined by your subclass:
97
98       store ( $self, $key, $data[, $expires_in] )
99           Associate $data with $key in the namespace, overwriting any
100           existing entry.  Called by "set". $data will contain any necessary
101           metadata, including expiration options, so you can just store it as
102           a single block.
103
104           $expires_in is optionally the number of seconds from now when the
105           entry will expire. This will only be passed if "expires_on_backend"
106           in CHI is set. If your driver does not support expiration, or if
107           you'd rather just let CHI manage expiration, you can ignore this.
108
109       fetch ( $self, $key )
110           Returns the data associated with $key in the namespace. Called by
111           "get".  The main CHI::Driver superclass will take care of
112           extracting out metadata like expiration options and determining if
113           the value has expired.
114
115       remove ( $self, $key )
116           Remove the data associated with the $key in the namespace.
117
118       clear ( $self )
119           Remove all data associated with the namespace. (Technically not
120           required, but the default implementation, which iterates over all
121           keys and calls "remove" for each, is very inefficient).
122
123   Overridable methods
124       The following methods have a default implementation, but MAY be
125       overridden by your subclass:
126
127       BUILD ( $self, $options )
128           Define the BUILD method if you want to process any options specific
129           to your driver.  This is a standard Moo/Moose feature.
130
131       fetch_multi_hashref ( $keys )
132           Override this if you want to efficiently process multiple fetches.
133           Return a hash reference from keys to fetched data. If a key is not
134           available, it may be left out of the hash or paired with undef. The
135           default method will iterate over $keys and call fetch for each.
136
137           This method is called by get_multi_arrayref and get_multi_hashref.
138
139       store_multi ( $key_data, $options )
140           Override this if you want to efficiently process multiple stores.
141           $key_data is a hash of keys and data that should be stored. The
142           default will iterate over $key_data and call store for each pair.
143
144           This method is called by set_multi.
145
146   Optional methods
147       The following methods have no default implementation, and MAY be
148       defined by your subclass, but are not required for basic cache
149       operations.
150
151       get_keys ( $self )
152           Return all keys in the namespace. It is acceptable to either
153           include or omit expired keys.
154
155       get_namespaces ( $self )
156           Return namespaces associated with the cache. It is acceptable to
157           either include or omit namespaces with no valid keys.
158

DISCARD POLICIES

160       You can create new discard policies for size aware caches, to choose
161       items to discard when the cache gets full. For example, the Memory
162       driver implements an LRU policy.
163
164       To implement a discard policy foo, define a subroutine
165       discard_policy_foo, which takes a driver object and returns a closure
166       that returns one key each time it is called. The closure should
167       maintain state so that each key is only returned once.
168
169       For example, here's the Memory driver's LRU implementation. It utilizes
170       a hash containing the last used time for each key.
171
172          sub discard_policy_lru {
173              my ($self) = @_;
174
175              my $last_used_time = $self->{metadata_for_namespace}->{last_used_time};
176              my @keys_in_lru_order =
177                sort { $last_used_time->{$a} <=> $last_used_time->{$b} } $self->get_keys;
178              return sub {
179                  shift(@keys_in_lru_order);
180              };
181          }
182
183       You can set the default discard policy for your driver by overriding
184       default_discard_policy; otherwise the default is 'arbitrary'.
185
186          sub default_discard_policy { 'lru' }
187

TESTING

189       CHI has a standard set of unit tests that should be used to ensure your
190       driver is fully implementing the CHI API.
191
192       To use CHI's tests (replacing MyDriver with the name of your driver):
193
194       •   Install Test::Class and add it to the build dependencies for your
195           distribution.
196
197       •   Add a module called CHI::Driver::MyDriver::t::CHIDriverTests to
198           your distribution containing:
199
200               package CHI::Driver::MyDriver::t::CHIDriverTests;
201               use strict;
202               use warnings;
203               use CHI::Test;
204               use base qw(CHI::t::Driver);
205
206               sub testing_driver_class { 'CHI::Driver::MyDriver' }
207
208               sub new_cache_options {
209                   my $self = shift;
210
211                   return (
212                       $self->SUPER::new_cache_options(),
213
214                       # Any necessary CHI->new parameters for your test driver
215                   );
216               }
217
218               1;
219
220       •   Add a test script called t/CHI-driver-tests.t to your distribution
221           containing:
222
223               #!perl -w
224               use strict;
225               use warnings;
226               use CHI::Driver::MyDriver::t::CHIDriverTests;
227               CHI::Driver::MyDriver::t::CHIDriverTests->runtests;
228
229       •   You may need to override other methods in
230           CHI::Driver::MyDriver::t::CHIDriverTests, e.g. to skip tests that
231           do not apply to your driver. See CHI::t::Driver::Memory and
232           CHI::t::Driver::File in this distribution for examples.
233
234   Test cleanup
235       You are responsible for cleaning up your datastore after tests are
236       done. The easiest way to do this is to place your datastore wholly
237       inside a temporary directory, or use a guard to remove it at process
238       end.
239
240       For example, the File, FastMmap, and DBI tests place all data inside a
241       tempdir that is automatically cleaned up at process end.
242

SEE ALSO

244       CHI
245

AUTHOR

247       Jonathan Swartz <swartz@pobox.com>
248
250       This software is copyright (c) 2021 by Jonathan Swartz.
251
252       This is free software; you can redistribute it and/or modify it under
253       the same terms as the Perl 5 programming language system itself.
254
255
256
257perl v5.36.0                      2022-07-22       CHI::Driver::Development(3)
Impressum