diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c6ff26 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +/blib/ +/.build/ +_build/ +cover_db/ +inc/ +Build +!Build/ +Build.bat +.last_cover_stats +/Makefile +/Makefile.old +/MANIFEST +/MANIFEST.bak +/META.yml +/META.json +/MYMETA.* +nytprof.out +/pm_to_blib +*.o +*.bs +/_eumm/ + +*.sublime-project +*.sublime-workspace \ No newline at end of file diff --git a/Changes b/Changes index 98c4a89..360e36c 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,19 @@ Revision history for Catalyst-Plugin-Session-Store-Redis +0.10 March 4th, 2016 + - Allow to pass any configuration parameter to Redis + - Force Redis at least 1.977 + - Update docs + +0.06 March 8th, 2014 + - Fix disconnection Redis Server + - Add option configuration redis_reconnect + - Removed Catalyst log debug + +0.05 + +0.04 + 0.03 December 12th, 2009 - Fix POD description - Fix logging typo (said 'Getting key' when it meant 'Setting key') diff --git a/Makefile.PL b/Makefile.PL index e796e89..9748893 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -7,9 +7,10 @@ license 'perl'; build_requires 'Test::More'; -requires 'Redis' => '0.0801'; +requires 'Redis' => '1.977'; requires 'Try::Tiny' => '0.02'; requires 'Catalyst::Plugin::Session' => '0.27'; +requires 'Module::Load' => '0'; WriteAll; diff --git a/README b/README deleted file mode 100644 index f0ef9c3..0000000 --- a/README +++ /dev/null @@ -1,54 +0,0 @@ -NAME - -Catalyst::Plugin::Session::Store::Redis - The great new Catalyst::Plugin::Session::Store::Redis! - -SYNOPSIS - - use Catalyst qw/ - Session - Session::Store::Redis - Session::State::Foo - /; - - MyApp->config->{session} = { - expires => 3600, - redis_server => '127.0.0.1:6379', - redis_debug => 0 # or 1! - }; - - # ... in an action: - $c->session->{foo} = 'bar'; # will be saved - -DESCRIPTION - -Catalyst::Plugin::Session::Store::Redis is a session storage plugin for -Catalyst that uses the Redis key-value database. - -NOTES - -Expired Sessions - -This store does B automatically expire sessions. You can call -C to clear any expired sessions. All sessions will -then be checked, one at a time. If a session has expired then it will be -deleted. - -WARNING - -This module is currently untested, outside of the unit tests it ships with. -It will eventually be used with a busy site, but is currently unproven. -Patches are welcome! - -AUTHOR - -Cory G Watson, C<< >> - -COPYRIGHT & LICENSE - -Copyright 2009 Cold Hard Code, LLC. - -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. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4e12e3 --- /dev/null +++ b/README.md @@ -0,0 +1,56 @@ +# NAME + +Catalyst::Plugin::Session::Store::Redis - Redis Session store for Catalyst + +# SYNOPSIS + + use Catalyst qw/ + Session + Session::Store::Redis + Session::State::Foo + /; + + MyApp->config->{Plugin::Session} = { + expires => 3600, + redis_server => '127.0.0.1:6379', + redis_debug => 0, # or 1! + redis_reconnect => 60 # 60 is default + implementation => 'Redis' # Redis by default, or you can use Redis::Fast + }; + + # ... in an action: + $c->session->{foo} = 'bar'; # will be saved + +# DESCRIPTION + +`Catalyst::Plugin::Session::Store::Redis` is a session storage plugin for +Catalyst that uses the Redis ([http://redis.io](http://redis.io)) key-value +database. + +# CONFIGURATION + +By default it will use 127.0.0.1:6379 as server, and enables autoreconnect after 60 if the connection fails. In addition +you can use any configuration parameter of `Redis` prefixing "redis\_" in the hash under the `Plugin::Session` + +# WARNING + +This module is currently untested, outside of the unit tests it ships with. +It will eventually be used with a busy site, but is currently unproven. +Patches are welcome! + +# AUTHORS + +Cory G Watson, `` +Yusuke Watase +luma +Gerard Ribugent Navarro `` + +# COPYRIGHT & LICENSE + +Copyright 2009 Cold Hard Code, LLC. + +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. diff --git a/lib/Catalyst/Plugin/Session/Store/Redis.pm b/lib/Catalyst/Plugin/Session/Store/Redis.pm index 43c9b37..410743a 100644 --- a/lib/Catalyst/Plugin/Session/Store/Redis.pm +++ b/lib/Catalyst/Plugin/Session/Store/Redis.pm @@ -6,13 +6,13 @@ use base qw/ Class::Data::Inheritable Catalyst::Plugin::Session::Store /; +use Module::Load; use MRO::Compat; use MIME::Base64 qw(encode_base64 decode_base64); -use Redis; use Storable qw/nfreeze thaw/; use Try::Tiny; -our $VERSION = '0.03'; +our $VERSION = '0.10'; __PACKAGE__->mk_classdata(qw/_session_redis_storage/); @@ -22,10 +22,10 @@ sub get_session_data { $c->_verify_redis_connection; if(my ($sid) = $key =~ /^expires:(.*)/) { - $c->log->debug("Getting expires key for $sid"); + $c->log->debug("Getting expires key for $sid") if $c->debug; return $c->_session_redis_storage->get($key); } else { - $c->log->debug("Getting $key"); + $c->log->debug("Getting $key") if $c->debug; my $data = $c->_session_redis_storage->get($key); if(defined($data)) { return thaw( decode_base64($data) ) @@ -41,20 +41,14 @@ sub store_session_data { $c->_verify_redis_connection; if(my ($sid) = $key =~ /^expires:(.*)/) { - $c->log->debug("Setting expires key for $sid: $data"); + $c->log->debug("Setting expires key for $sid: $data") if $c->debug; $c->_session_redis_storage->set($key, $data); } else { - $c->log->debug("Setting $key"); + $c->log->debug("Setting $key") if $c->debug; $c->_session_redis_storage->set($key, encode_base64(nfreeze($data))); } - # We use expire, not expireat because it's a 1.2 feature and as of this - # release, 1.2 isn't done yet. - my $exp = $c->session_expires; - my $duration = $exp - time; - $c->_session_redis_storage->expire($key, $duration); - # $c->_session_redis_storage->expireat($key, $exp); - + $c->_session_redis_storage->expireat($key, $c->session_expires); return; } @@ -63,7 +57,7 @@ sub delete_session_data { $c->_verify_redis_connection; - $c->log->debug("Deleting: $key"); + $c->log->debug("Deleting: $key") if $c->debug; $c->_session_redis_storage->del($key); return; @@ -89,13 +83,23 @@ sub _verify_redis_connection { my $cfg = $c->_session_plugin_config; try { - $c->_session_redis_storage->ping; + $c->_session_redis_storage->ping or die "failed to ping"; } catch { + # Exract redis options + my %redisCfg = map { + (my $k = $_) =~ s/^redis_//; + ($k => $cfg->{$_}) + } grep{ $_ =~ m/^redis_/ } keys %$cfg; + + $redisCfg{server} ||= '127.0.0.1:6379' if (!exists $redisCfg{sock}); + $redisCfg{debug} ||= 0; + $redisCfg{redis_reconnect} ||= 60; + + my $implementation = $cfg->{implementation} || 'Redis'; + load $implementation; + $c->_session_redis_storage( - Redis->new( - server => $cfg->{redis_server} || '127.0.0.1:6379', - debug => $cfg->{redis_debug} || 0 - ) + $implementation->new(%redisCfg) ); }; } @@ -115,11 +119,13 @@ Catalyst::Plugin::Session::Store::Redis - Redis Session store for Catalyst Session::Store::Redis Session::State::Foo /; - + MyApp->config->{Plugin::Session} = { expires => 3600, redis_server => '127.0.0.1:6379', - redis_debug => 0 # or 1! + redis_debug => 0, # or 1! + redis_reconnect => 60 # 60 is default + implementation => 'Redis' # Redis by default, or you can use Redis::Fast }; # ... in an action: @@ -128,21 +134,14 @@ Catalyst::Plugin::Session::Store::Redis - Redis Session store for Catalyst =head1 DESCRIPTION C is a session storage plugin for -Catalyst that uses the Redis (L) key-value +Catalyst that uses the Redis (L) key-value database. -=head1 NOTES - -=over 4 - -=item B +=head1 CONFIGURATION -This store does B automatically expire sessions. You can call -C to clear any expired sessions. All sessions will -then be checked, one at a time. If a session has expired then it will be -deleted. +By default it will use 127.0.0.1:6379 as server, and enables autoreconnect after 60 if the connection fails. In addition +you can use any configuration parameter of C prefixing "redis_" in the hash under the C -=back =head1 WARNING @@ -150,9 +149,12 @@ This module is currently untested, outside of the unit tests it ships with. It will eventually be used with a busy site, but is currently unproven. Patches are welcome! -=head1 AUTHOR +=head1 AUTHORS Cory G Watson, C<< >> +Yusuke Watase +luma +Gerard Ribugent Navarro C<< >> =head1 COPYRIGHT & LICENSE diff --git a/t/ping.t b/t/ping.t new file mode 100644 index 0000000..95f0a5d --- /dev/null +++ b/t/ping.t @@ -0,0 +1,48 @@ +#/usr/bin/env perl +#=============================================================================== +#Last Modified: 2014/09/03 +#=============================================================================== +use strict; +use warnings; +use Test::More; +use Redis; + +unless ($ENV{SESSION_STORE_REDIS_PING} ) { + plan skip_all => 'Must set SESSION_STORE_REDIS_PING environment variable'; +} +eval { require Test::RedisServer } + or plan skip_all => "Test requires 'Test::RedisServer'"; +eval { require Net::EmptyPort } + or plan skip_all => "Test requires 'Net::EmptyPort'"; + +my $redis_server = eval { Test::RedisServer->new( + conf => { + port => Net::EmptyPort::empty_port(), + timeout => 1, + } + ) } + or plan skip_all => 'redis-server is required to this test'; + +my %connect_info = $redis_server->connect_info; +$connect_info{server} =~ s/0\.0\.0\.0/localhost/; + +{ + package RedisTimeoutTest; + use Catalyst qw/Session Session::Store::Redis Session::State::Cookie/; + RedisTimeoutTest->config( + 'Plugin::Session' => { + expires => 20, + redis_server => $connect_info{server}, + }); + RedisTimeoutTest->setup; +} + +my $c = RedisTimeoutTest->new; +$c->session; +my $sid = $c->sessionid; +$c->store_session_data($sid, { key => 456}); +sleep 2; +my $res = eval { $c->get_session_data($sid)->{key} } ; +$res = $@ if $@; +is (456, $res, 'reconnect'); +done_testing;