File Coverage

blib/lib/Catalyst/Plugin/Session/Store/FastMmap.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Catalyst::Plugin::Session::Store::FastMmap;
2              
3 1     1   42525 use strict;
  1         3  
  1         38  
4 1     1   700 use Moose;
  0            
  0            
5             use MRO::Compat;
6             use namespace::clean -except => 'meta';
7              
8             with 'Catalyst::ClassData';
9             with 'MooseX::Emulate::Class::Accessor::Fast';
10             extends 'Catalyst::Plugin::Session::Store';
11              
12             use Cache::FastMmap;
13             use Path::Class ();
14             use File::Spec ();
15             use Catalyst::Utils ();
16              
17             our $VERSION = '0.16';
18              
19             __PACKAGE__->mk_classdata(qw/_session_fastmmap_storage/);
20              
21             =head1 NAME
22              
23             Catalyst::Plugin::Session::Store::FastMmap - FastMmap session storage backend.
24              
25             =head1 SYNOPSIS
26              
27             use Catalyst qw/Session Session::Store::FastMmap Session::State::Foo/;
28              
29             MyApp->config(
30             'Plugin::Session' => {
31             expires => 3600,
32             storage => '/tmp/session'
33             },
34             );
35              
36             # ... in an action:
37             $c->session->{foo} = 'bar'; # will be saved
38              
39             =head1 DESCRIPTION
40              
41             C<Catalyst::Plugin::Session::Store::FastMmap> is a fast session storage plugin
42             for Catalyst that uses an mmap'ed file to act as a shared memory interprocess
43             cache. It is based on L<Cache::FastMmap>.
44              
45             =head2 METHODS
46              
47             =over 4
48              
49             =item get_session_data
50              
51             =item store_session_data
52              
53             =item delete_session_data
54              
55             =item delete_expired_sessions
56              
57             These are implementations of the required methods for a store. See
58             L<Catalyst::Plugin::Session::Store>.
59              
60             =item get_and_set_session_data
61              
62             This is the optional method for atomic write semantics. See
63             L<Catalyst::Plugin::Session::AtomicWrite>.
64              
65             =cut
66              
67             sub get_session_data {
68             my ( $c, $sid ) = @_;
69             $c->_session_fastmmap_storage->get($sid);
70             }
71              
72             sub store_session_data {
73             my ( $c, $sid, $data ) = @_;
74             $c->_session_fastmmap_storage->set( $sid, $data )
75             or Catalyst::Exception->throw("store_session: data too large");
76             }
77              
78             sub delete_session_data {
79             my ( $c, $sid ) = @_;
80             $c->_session_fastmmap_storage->remove($sid);
81             }
82              
83             sub delete_expired_sessions { } # unsupported
84              
85             sub get_and_set_session_data {
86             my ( $c, $sid, $sub ) = @_;
87             $c->_session_fastmmap_storage->get_and_set( $sid, sub {
88             my ( $key, $data ) = @_;
89             my $new = $sub->( $key, $data );
90             return $new;
91             });
92             }
93              
94             =item setup_session
95              
96             Sets up the session cache file.
97              
98             =cut
99              
100             sub setup_session {
101             my $c = shift;
102              
103             $c->maybe::next::method(@_);
104              
105             my $tmpdir = Catalyst::Utils::class2tempdir($c)
106             || Catalyst::Exception->throw("Can't determine tempdir for $c");
107              
108             my $file = $c->_session_plugin_config->{storage} ||=
109             File::Spec->catfile( # Cache::FastMmap doesn't like Path::Class objects
110             $tmpdir,
111             "session_data",
112             );
113              
114             my $dir = Path::Class::file($file)->parent;
115              
116             unless (-d $dir) {
117             $dir->mkpath($c->debug);
118             }
119              
120             if ($c->debug) {
121             $c->log->debug("Session Store file: $file");
122             }
123              
124             my $cfg = $c->_session_plugin_config;
125              
126             $c->_session_fastmmap_storage(
127             Cache::FastMmap->new(
128             raw_values => 0,
129             share_file => ($file . ''), # force serialize in case it is a Path::Class object
130             (
131             map { $_ => $cfg->{$_} }
132             grep { exists $cfg->{$_} } qw/init_file cache_size page_size unlink_on_exit/
133             ),
134             )
135             );
136             }
137              
138             =back
139              
140             =head1 CAVEATS
141              
142             Very loaded sites with lots of data in the session hash may have old sessions
143             expired prematurely, due to the LRU caching policy employed by
144             L<Cache::FastMmap>. To get around this you can increase the C<cache_size>
145             parameter, or switch session storage backends.
146             L<Cache::FastMmap> defaults to around 5mb (89 * 64k).
147              
148             This is particularly inappropriate for use as a backend for e.g.
149             L<Catalyst::Plugin::Session::PerUser>, for example.
150              
151             As L<Cache::FastMmap> is not "thread-safe" (at least version 1.30 and before)
152             therefore also this module does not work in multi-threaded environment.
153             It is "fork-safe", however keep in mind that on Win32 the perl "fork" call is
154             implemented as an emulation via threads - that is the reason why you cannot use
155             this store for example when running you catalyst application on Win32 platform
156             with L<Catalyst::Engine::HTTP::Prefork> engine.
157              
158             =head1 CONFIGURATION
159              
160             These parameters are placed in the hash under the C<Plugin::Session> key in the
161             configuration hash.
162              
163             =over 4
164              
165             =item storage
166              
167             Specifies the file to be used for the sharing of session data. The default
168             value will use L<File::Spec> to find the default tempdir, and use a file named
169             C<MyApp_session_data>, where C<MyApp> is replaced with the appname.
170              
171             Note that the file will be created with mode 0640, which means that it
172             will only be writeable by processes running with the same uid as the
173             process that creates the file. If this may be a problem, for example
174             if you may try to debug the program as one user and run it as another,
175             specify a filename like C<< /tmp/session-$> >>, which includes the
176             UID of the process in the filename.
177              
178             =item init_file
179              
180             =item cache_size
181              
182             =item unlink_on_exit
183              
184             See the L<Cache::FastMmap> documentation for the meaning of these keys. If
185             these keys are not present L<Cache::FastMmap>'s defaults will be used.
186              
187             =back
188              
189             =head1 SEE ALSO
190              
191             L<Catalyst>, L<Catalyst::Plugin::Session>, L<Cache::FastMmap>.
192              
193             =head1 AUTHORS
194              
195             This module is derived from L<Catalyst::Plugin::Session::FastMmap> code, and
196             has been heavily modified since.
197              
198             Andrew Ford
199             Andy Grundman
200             Christian Hansen
201             Yuval Kogman, <nothingmuch@woobling.org>
202             Marcus Ramberg
203             Sebastian Riedel
204             Tomas Doran, (t0m) <bobtfish@bobtfish.net>
205              
206             =head1 COPYRIGHT
207              
208             Copyright (c) 2005 - 2012
209             the Catalyst::Plugin::Session::Store::FastMmap L</AUTHORS>
210             as listed above.
211              
212             =head1 LICENSE
213              
214             This program is free software, you can redistribute it and/or modify it
215             under the same terms as Perl itself.
216              
217             =cut
218              
219             1;