Bug 16229: Deep copy on first L2 fetch
[koha.git] / Koha / Cache.pm
1 package Koha::Cache;
2
3 # Copyright 2009 Chris Cormack and The Koha Dev Team
4 # Parts copyright 2012-2013 C & P Bibliography Services
5 #
6 # This file is part of Koha.
7 #
8 # Koha is free software; you can redistribute it and/or modify it
9 # under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # Koha is distributed in the hope that it will be useful, but
14 # WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with Koha; if not, see <http://www.gnu.org/licenses>.
20
21 =head1 NAME
22
23 Koha::Cache - Handling caching of html and Objects for Koha
24
25 =head1 SYNOPSIS
26
27   use Koha::Cache;
28   my $cache = Koha::Cache->new({cache_type => $cache_type, %params});
29
30 =head1 DESCRIPTION
31
32 Koha caching routines. This class provides two interfaces for cache access.
33 The first, traditional OO interface provides the following functions:
34
35 =head1 FUNCTIONS
36
37 =cut
38 use strict;
39 use warnings;
40 use Carp;
41 use Clone qw( clone );
42 use Module::Load::Conditional qw(can_load);
43 use Koha::Cache::Object;
44
45 use base qw(Class::Accessor);
46
47 __PACKAGE__->mk_ro_accessors(
48     qw( cache memcached_cache fastmmap_cache memory_cache ));
49
50 our %L1_cache;
51
52 =head2 get_instance
53
54     my $cache = Koha::Cache->get_instance();
55
56 This gets a shared instance of the cache, set up in a very default way. This is
57 the recommended way to fetch a cache object. If possible, it'll be
58 persistent across multiple instances.
59
60 =cut
61
62 our $singleton_cache;
63 sub get_instance {
64     my ($class) = @_;
65     $singleton_cache = $class->new() unless $singleton_cache;
66     return $singleton_cache;
67 }
68
69 =head2 new
70
71 Create a new Koha::Cache object. This is required for all cache-related functionality.
72
73 =cut
74
75 sub new {
76     my ( $class, $self ) = @_;
77     $self->{'default_type'} =
78          $self->{cache_type}
79       || $ENV{CACHING_SYSTEM}
80       || 'memcached';
81
82     $ENV{DEBUG} && carp "Default caching system: $self->{'default_type'}";
83
84     $self->{'timeout'}   ||= 0;
85     $self->{'namespace'} ||= $ENV{MEMCACHED_NAMESPACE} || 'koha';
86
87     if ( $self->{'default_type'} eq 'memcached'
88         && can_load( modules => { 'Cache::Memcached::Fast' => undef } )
89         && _initialize_memcached($self)
90         && defined( $self->{'memcached_cache'} ) )
91     {
92         $self->{'cache'} = $self->{'memcached_cache'};
93     }
94
95     if ( $self->{'default_type'} eq 'fastmmap'
96       && defined( $ENV{GATEWAY_INTERFACE} )
97       && can_load( modules => { 'Cache::FastMmap' => undef } )
98       && _initialize_fastmmap($self)
99       && defined( $self->{'fastmmap_cache'} ) )
100     {
101         $self->{'cache'} = $self->{'fastmmap_cache'};
102     }
103
104     # Unless memcache or fastmmap has already been picked, use memory_cache
105     unless ( defined( $self->{'cache'} ) ) {
106         if ( can_load( modules => { 'Cache::Memory' => undef } )
107             && _initialize_memory($self) )
108         {
109                 $self->{'cache'} = $self->{'memory_cache'};
110         }
111     }
112
113     $ENV{DEBUG} && carp "Selected caching system: " . ($self->{'cache'} // 'none');
114
115     return
116       bless $self,
117       $class;
118 }
119
120 sub _initialize_memcached {
121     my ($self) = @_;
122     my @servers =
123       split /,/, $self->{'cache_servers'}
124       ? $self->{'cache_servers'}
125       : ($ENV{MEMCACHED_SERVERS} || '');
126     return if !@servers;
127
128     $ENV{DEBUG}
129       && carp "Memcached server settings: "
130       . join( ', ', @servers )
131       . " with "
132       . $self->{'namespace'};
133     # Cache::Memcached::Fast doesn't allow a default expire time to be set
134     # so we force it on setting.
135     my $memcached = Cache::Memcached::Fast->new(
136         {
137             servers            => \@servers,
138             compress_threshold => 10_000,
139             namespace          => $self->{'namespace'},
140             utf8               => 1,
141         }
142     );
143     # Ensure we can actually talk to the memcached server
144     my $ismemcached = $memcached->set('ismemcached','1');
145     return $self unless $ismemcached;
146     $self->{'memcached_cache'} = $memcached;
147     return $self;
148 }
149
150 sub _initialize_fastmmap {
151     my ($self) = @_;
152     my ($cache, $share_file);
153
154     # Temporary workaround to catch fatal errors when: C4::Context module
155     # is not loaded beforehand, or Cache::FastMmap init fails for whatever
156     # other reason (e.g. due to permission issues - see Bug 13431)
157     eval {
158         $share_file = join( '-',
159             "/tmp/sharefile-koha", $self->{'namespace'},
160             C4::Context->config('hostname'), C4::Context->config('database') );
161
162         $cache = Cache::FastMmap->new(
163             'share_file'  => $share_file,
164             'expire_time' => $self->{'timeout'},
165             'unlink_on_exit' => 0,
166         );
167     };
168     if ( $@ ) {
169         warn "FastMmap cache initialization failed: $@";
170         return;
171     }
172     return unless defined $cache;
173     $self->{'fastmmap_cache'} = $cache;
174     return $self;
175 }
176
177 sub _initialize_memory {
178     my ($self) = @_;
179
180     # Default cache time for memory is _always_ short unless it's specially
181     # defined, to allow it to work reliably in a persistent environment.
182     my $cache = Cache::Memory->new(
183         'namespace'       => $self->{'namespace'},
184         'default_expires' => "$self->{'timeout'} sec" || "10 sec",
185     );
186     $self->{'memory_cache'} = $cache;
187     # Memory cache can't handle complex types for some reason, so we use its
188     # freeze and thaw functions.
189     $self->{ref($cache) . '_set'} = sub {
190         my ($key, $val, $exp) = @_;
191         # Refer to set_expiry in Cache::Entry for why we do this 'sec' thing.
192         $exp = "$exp sec" if defined $exp;
193         # Because we need to use freeze, it must be a reference type.
194         $cache->freeze($key, [$val], $exp);
195     };
196     $self->{ref($cache) . '_get'} = sub {
197         my $res = $cache->thaw(shift);
198         return unless defined $res;
199         return $res->[0];
200     };
201     return $self;
202 }
203
204 =head2 is_cache_active
205
206 Routine that checks whether or not a default caching method is active on this
207 object.
208
209 =cut
210
211 sub is_cache_active {
212     my $self = shift;
213     return $self->{'cache'} ? 1 : 0;
214 }
215
216 =head2 set_in_cache
217
218     $cache->set_in_cache($key, $value, [$options]);
219
220 Save a value to the specified key in the cache. A hashref of options may be
221 specified.
222
223 The possible options are:
224
225 =over
226
227 =item expiry
228
229 Expiry time of this cached entry in seconds.
230
231 =item deepcopy
232
233 If set, this will perform a deep copy of the item when it's retrieved. This
234 means that it'll be safe if something later modifies the result of the
235 function. Will be ignored in situations where the same behaviour comes from
236 the caching layer anyway.
237
238 =item cache
239
240 The cache object to use if you want to provide your own. It should be an
241 instance of C<Cache::*> and follow the same interface as L<Cache::Memcache>.
242
243 =back
244
245 =cut
246
247 sub set_in_cache {
248     my ( $self, $key, $value, $options, $_cache) = @_;
249     # This is a bit of a hack to support the old API in case things still use it
250     if (defined $options && (ref($options) ne 'HASH')) {
251         my $new_options;
252         $new_options->{expiry} = $options;
253         $new_options->{cache} = $_cache if defined $_cache;
254         $options = $new_options;
255     }
256
257     # the key mustn't contain whitespace (or control characters) for memcache
258     # but shouldn't be any harm in applying it globally.
259     $key =~ s/[\x00-\x20]/_/g;
260
261     my $cache = $options->{cache} || 'cache';
262     croak "No key" unless $key;
263     $ENV{DEBUG} && carp "set_in_cache for $key";
264
265     return unless ( $self->{$cache} && ref( $self->{$cache} ) =~ m/^Cache::/ );
266     my $expiry = $options->{expiry};
267     $expiry //= $self->{timeout};
268     my $set_sub = $self->{ref($self->{$cache}) . "_set"};
269
270     # Set in L1 cache
271     $L1_cache{ $key } = $value;
272
273     # We consider an expiry of 0 to be inifinite
274     if ( $expiry ) {
275         return $set_sub
276           ? $set_sub->( $key, $value, $expiry )
277           : $self->{$cache}->set( $key, $value, $expiry );
278     }
279     else {
280         return $set_sub
281           ? $set_sub->( $key, $value )
282           : $self->{$cache}->set( $key, $value );
283     }
284 }
285
286 =head2 get_from_cache
287
288     my $value = $cache->get_from_cache($key, [ $options ]);
289
290 Retrieve the value stored under the specified key in the default cache.
291
292 The options can set an unsafe flag to avoid a deep copy.
293 When this flag is set, you have to know what you are doing!
294 If you are retrieving a structure and modify it, you will modify the contain
295 of the cache!
296
297 =cut
298
299 sub get_from_cache {
300     my ( $self, $key, $options ) = @_;
301     my $cache  = $options->{cache}  || 'cache';
302     my $unsafe = $options->{unsafe} || 0;
303     $key =~ s/[\x00-\x20]/_/g;
304     croak "No key" unless $key;
305     $ENV{DEBUG} && carp "get_from_cache for $key";
306     return unless ( $self->{$cache} && ref( $self->{$cache} ) =~ m/^Cache::/ );
307
308     # Return L1 cache value if exists
309     if ( exists $L1_cache{$key} ) {
310         # No need to deep copy if it's a scalar
311         # Or if we do not need to deep copy
312         return $L1_cache{$key}
313             if not ref $L1_cache{$key} or $unsafe;
314         return clone $L1_cache{$key};
315     }
316
317     my $get_sub = $self->{ref($self->{$cache}) . "_get"};
318     my $value = $get_sub ? $get_sub->($key) : $self->{$cache}->get($key);
319
320     # Update the L1 cache when fetching the L2 cache
321     # Otherwise the L1 cache won't ever be populated
322     $L1_cache{$key} = $value;
323
324     $value = clone $value if ref $L1_cache{$key} and not $unsafe;
325
326     return $value;
327 }
328
329 =head2 clear_from_cache
330
331     $cache->clear_from_cache($key);
332
333 Remove the value identified by the specified key from the default cache.
334
335 =cut
336
337 sub clear_from_cache {
338     my ( $self, $key, $cache ) = @_;
339     $key =~ s/[\x00-\x20]/_/g;
340     $cache ||= 'cache';
341     croak "No key" unless $key;
342     return unless ( $self->{$cache} && ref( $self->{$cache} ) =~ m/^Cache::/ );
343
344     # Clear from L1 cache
345     delete $L1_cache{$key};
346
347     return $self->{$cache}->delete($key)
348       if ( ref( $self->{$cache} ) =~ m'^Cache::Memcached' );
349     return $self->{$cache}->remove($key);
350 }
351
352 =head2 flush_all
353
354     $cache->flush_all();
355
356 Clear the entire default cache.
357
358 =cut
359
360 sub flush_all {
361     my ( $self, $cache ) = shift;
362     $cache ||= 'cache';
363     return unless ( $self->{$cache} && ref( $self->{$cache} ) =~ m/^Cache::/ );
364
365     $self->flush_L1_cache();
366
367     return $self->{$cache}->flush_all()
368       if ( ref( $self->{$cache} ) =~ m'^Cache::Memcached' );
369     return $self->{$cache}->clear();
370 }
371
372 sub flush_L1_cache {
373     my( $self ) = @_;
374     %L1_cache = ();
375 }
376
377 =head1 TIED INTERFACE
378
379 Koha::Cache also provides a tied interface which enables users to provide a
380 constructor closure and (after creation) treat cached data like normal reference
381 variables and rely on the cache Just Working and getting updated when it
382 expires, etc.
383
384     my $cache = Koha::Cache->new();
385     my $data = 'whatever';
386     my $scalar = Koha::Cache->create_scalar(
387         {
388             'key'         => 'whatever',
389             'timeout'     => 2,
390             'constructor' => sub { return $data; },
391         }
392     );
393     print "$$scalar\n"; # Prints "whatever"
394     $data = 'somethingelse';
395     print "$$scalar\n"; # Prints "whatever" because it is cached
396     sleep 2; # Wait until the cache entry has expired
397     print "$$scalar\n"; # Prints "somethingelse"
398
399     my $hash = Koha::Cache->create_hash(
400         {
401             'key'         => 'whatever',
402             'timeout'     => 2,
403             'constructor' => sub { return $data; },
404         }
405     );
406     print "$$variable\n"; # Prints "whatever"
407
408 The gotcha with this interface, of course, is that the variable returned by
409 create_scalar and create_hash is a I<reference> to a tied variable and not a
410 tied variable itself.
411
412 The tied variable is configured by means of a hashref passed in to the
413 create_scalar and create_hash methods. The following parameters are supported:
414
415 =over
416
417 =item I<key>
418
419 Required. The key to use for identifying the variable in the cache.
420
421 =item I<constructor>
422
423 Required. A closure (or reference to a function) that will return the value that
424 needs to be stored in the cache.
425
426 =item I<preload>
427
428 Optional. A closure (or reference to a function) that gets run to initialize
429 the cache when creating the tied variable.
430
431 =item I<arguments>
432
433 Optional. Array reference with the arguments that should be passed to the
434 constructor function.
435
436 =item I<timeout>
437
438 Optional. The cache timeout in seconds for the variable. Defaults to 600
439 (ten minutes).
440
441 =item I<cache_type>
442
443 Optional. Which type of cache to use for the variable. Defaults to whatever is
444 set in the environment variable CACHING_SYSTEM. If set to 'null', disables
445 caching for the tied variable.
446
447 =item I<allowupdate>
448
449 Optional. Boolean flag to allow the variable to be updated directly. When this
450 is set and the variable is used as an l-value, the cache will be updated
451 immediately with the new value. Using this is probably a bad idea on a
452 multi-threaded system. When I<allowupdate> is not set to true, using the
453 tied variable as an l-value will have no effect.
454
455 =item I<destructor>
456
457 Optional. A closure (or reference to a function) that should be called when the
458 tied variable is destroyed.
459
460 =item I<unset>
461
462 Optional. Boolean flag to tell the object to remove the variable from the cache
463 when it is destroyed or goes out of scope.
464
465 =item I<inprocess>
466
467 Optional. Boolean flag to tell the object not to refresh the variable from the
468 cache every time the value is desired, but rather only when the I<local> copy
469 of the variable is older than the timeout.
470
471 =back
472
473 =head2 create_scalar
474
475     my $scalar = Koha::Cache->create_scalar(\%params);
476
477 Create scalar tied to the cache.
478
479 =cut
480
481 sub create_scalar {
482     my ( $self, $args ) = @_;
483
484     $self->_set_tied_defaults($args);
485
486     tie my $scalar, 'Koha::Cache::Object', $args;
487     return \$scalar;
488 }
489
490 sub create_hash {
491     my ( $self, $args ) = @_;
492
493     $self->_set_tied_defaults($args);
494
495     tie my %hash, 'Koha::Cache::Object', $args;
496     return \%hash;
497 }
498
499 sub _set_tied_defaults {
500     my ( $self, $args ) = @_;
501
502     $args->{'timeout'}   = '600' unless defined( $args->{'timeout'} );
503     $args->{'inprocess'} = '0'   unless defined( $args->{'inprocess'} );
504     unless ( $args->{cache_type} and lc( $args->{cache_type} ) eq 'null' ) {
505         $args->{'cache'} = $self;
506         $args->{'cache_type'} ||= $ENV{'CACHING_SYSTEM'};
507     }
508
509     return $args;
510 }
511
512 =head1 EXPORT
513
514 None by default.
515
516 =head1 SEE ALSO
517
518 Koha::Cache::Object
519
520 =head1 AUTHOR
521
522 Chris Cormack, E<lt>chris@bigballofwax.co.nzE<gt>
523 Paul Poulain, E<lt>paul.poulain@biblibre.comE<gt>
524 Jared Camins-Esakov, E<lt>jcamins@cpbibliography.comE<gt>
525
526 =cut
527
528 1;
529
530 __END__