package Plack::Session::Store::Redis;
use strict;
use warnings;
use parent 'Plack::Session::Store';
use Redis;
use JSON;
use Plack::Util::Accessor qw/prefix redis_factory redis expires server serializer deserializer/;
=head1 NAME
Plack::Session::Store::Redis - Redis based session store for Plack apps.
=head1 VERSION
Version 0.05
=cut
our $VERSION = '0.05';
=head1 SYNOPSIS
use Plack::Builder;
use Plack::Middleware::Session;
use Plack::Session::Store::Redis;
my $app = sub { ... };
builder {
enable 'Session', store => 'Redis';
$app;
};
=head1 DESCRIPTION
This module will store Plack session data on a redis server. NOTE:
only works with redis 1.2.x, which appears to be a limitation of
Redis.pm.
=head1 METHODS
=head2 new( %params )
Create a instance of this module. No parameters are required, but
there are a few defaults that can be changed. You can set the IP
address of the server with the 'host' option, and the port with
'port'. By default all of the keys in Redis will be prefixed with
"session", but this can be changed with the 'prefix' option. You
can also provide an 'expires' option that will be used to set an
expiration on the redis key.
=cut
sub new {
my ($class, %params) = @_;
my $server = $ENV{REDIS_SERVER} ||
($params{host} || '127.0.0.1').":".
($params{port} || 6379);
my $redis_factory = $params{redis_factory} || sub { Redis->new(server => $server); };
my $self = {
prefix => $params{prefix} || 'session',
redis => $params{redis} || $redis_factory->(),
redis_factory => $redis_factory,
server => $params{server} || $server,
expires => $params{expires} || undef,
serializer => $params{serializer} || sub { encode_json($_[0]); },
deserializer => $params{deserializer} || sub { decode_json($_[0]); }
};
bless $self, $class;
}
=head2 fetch( $session_id )
Fetches a session object from the database.
=cut
sub fetch {
my ($self, $session_id) = @_;
my $session = $self->_exec("get", $session_id);
return $session ? $self->{deserializer}($session) : ();
}
sub _exec {
my ($self, $command, $session, @args) = @_;
unshift @args, $self->prefix."_".$session;
my $ret = eval {$self->redis->$command(@args)};
if ($@) {
$self->redis($self->redis_factory->());
$ret = $self->redis->$command(@args);
}
if ($self->expires and ($command eq "get" or $command eq "set")) {
$self->redis->expire($args[0], $self->expires);
}
return $ret;
}
=head2 store( $session_id, \%session_obj )
Stores a session object in the database.
=cut
sub store {
my ($self, $session_id, $session_obj) = @_;
$self->_exec("set", $session_id, $self->{serializer}($session_obj));
}
=head2 remove( $session_id )
Removes the session object from the database.
=cut
sub remove {
my ($self, $session_id) = @_;
$self->_exec("del", $session_id);
}
=head1 AUTHOR
Lee Aylward, C<< <leedo at cpan.org> >>
=head1 BUGS
Please report any bugs or feature requests to
C<bug-plack-session-store-redis at rt.cpan.org>, or through the web
interface at
L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Plack-Session-Store-Redis>.
I will be notified, and then you'll automatically be notified of
progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Plack::Session::Store::Redis
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Plack-Session-Store-Redis>
=item * AnnoCPAN: Annotated CPAN documentation
L<http://annocpan.org/dist/Plack-Session-Store-Redis>
=item * CPAN Ratings
L<http://cpanratings.perl.org/d/Plack-Session-Store-Redis>
=item * Search CPAN
L<http://search.cpan.org/dist/Plack-Session-Store-Redis/>
=back
=head1 ACKNOWLEDGEMENTS
=head1 LICENSE AND COPYRIGHT
Copyright 2010 Lee Aylward.
This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.
See http://dev.perl.org/licenses/ for more information.
=cut
1; # End of Plack::Session::Store::Redis