redis-store 0.3.7 → 0.3.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of redis-store might be problematic. Click here for more details.
- data/.gitignore +4 -0
- data/Gemfile +13 -7
- data/README.md +11 -1
- data/Rakefile +19 -5
- data/VERSION +1 -1
- data/lib/cache/merb/redis_store.rb +6 -6
- data/lib/cache/rails/redis_store.rb +10 -10
- data/lib/cache/sinatra/redis_store.rb +14 -11
- data/lib/rack/cache/redis_entitystore.rb +2 -2
- data/lib/rack/cache/redis_metastore.rb +5 -5
- data/lib/rack/session/rails.rb +61 -0
- data/lib/rack/session/redis.rb +10 -10
- data/lib/redis-store.rb +8 -4
- data/lib/redis/distributed_marshaled.rb +18 -0
- data/lib/redis/factory.rb +26 -0
- data/lib/redis/marshaled_client.rb +54 -0
- data/lib/redis/namespace.rb +9 -0
- data/redis-store.gemspec +18 -13
- data/spec/cache/merb/redis_store_spec.rb +9 -14
- data/spec/cache/rails/redis_session_store_spec.rb +77 -0
- data/spec/cache/rails/redis_store_spec.rb +13 -17
- data/spec/cache/sinatra/redis_store_spec.rb +9 -14
- data/spec/config/master.conf +5 -5
- data/spec/config/single.conf +5 -5
- data/spec/config/slave.conf +6 -6
- data/spec/rack/cache/entitystore/redis_spec.rb +21 -11
- data/spec/rack/cache/metastore/redis_spec.rb +169 -16
- data/spec/rack/session/redis_spec.rb +7 -11
- data/spec/redis/distributed_marshaled_redis_spec.rb +9 -11
- data/spec/redis/factory_spec.rb +68 -0
- data/spec/redis/marshaled_client_spec.rb +54 -0
- data/spec/spec_helper.rb +11 -5
- data/tasks/redis.tasks.rb +16 -5
- metadata +28 -12
- data/lib/redis/distributed_marshaled_redis.rb +0 -10
- data/lib/redis/marshaled_redis.rb +0 -33
- data/lib/redis/redis_factory.rb +0 -27
- data/spec/redis/marshaled_redis_spec.rb +0 -54
- data/spec/redis/redis_factory_spec.rb +0 -34
data/.gitignore
CHANGED
data/Gemfile
CHANGED
@@ -1,9 +1,15 @@
|
|
1
|
-
|
2
|
-
gem "redis
|
1
|
+
source :gemcutter
|
2
|
+
gem "redis", "1.0.5"
|
3
3
|
|
4
4
|
# testing gems
|
5
|
-
|
6
|
-
gem "
|
7
|
-
gem "
|
8
|
-
gem "
|
9
|
-
|
5
|
+
group :testing do
|
6
|
+
gem "ruby-debug"
|
7
|
+
gem "rspec"
|
8
|
+
gem "rack", "1.0.0"
|
9
|
+
gem "rack-cache"
|
10
|
+
gem "activesupport", "2.3.5"
|
11
|
+
gem "actionpack", "2.3.5"
|
12
|
+
gem "merb"
|
13
|
+
gem "jeweler"
|
14
|
+
gem "git"
|
15
|
+
end
|
data/README.md
CHANGED
@@ -73,7 +73,17 @@ Provides a Redis store for Rack::Session. See [http://rack.rubyforge.org/doc/Rac
|
|
73
73
|
|
74
74
|
### Sinatra
|
75
75
|
|
76
|
-
|
76
|
+
require "sinatra"
|
77
|
+
require "redis-store"
|
78
|
+
|
79
|
+
class MyApp < Sinatra::Base
|
80
|
+
use Rack::Session::Redis
|
81
|
+
|
82
|
+
get "/" do
|
83
|
+
session[:visited_at] = DateTime.now.to_s # This is stored in Redis
|
84
|
+
"Hello, visitor."
|
85
|
+
end
|
86
|
+
end
|
77
87
|
|
78
88
|
## Rack::Cache
|
79
89
|
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
$:.unshift 'lib'
|
2
|
+
require 'rubygems'
|
2
3
|
require 'rake'
|
3
4
|
require 'rake/testtask'
|
4
5
|
require 'rake/rdoctask'
|
@@ -9,17 +10,18 @@ task :default => "spec:suite"
|
|
9
10
|
begin
|
10
11
|
require "jeweler"
|
11
12
|
Jeweler::Tasks.new do |gemspec|
|
12
|
-
gemspec.name = "redis-store"
|
13
|
+
gemspec.name = "#{ENV["GEM_PREFIX"]}redis-store"
|
13
14
|
gemspec.summary = "Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks."
|
14
15
|
gemspec.description = "Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks."
|
15
16
|
gemspec.email = "guidi.luca@gmail.com"
|
16
17
|
gemspec.homepage = "http://github.com/jodosha/redis-store"
|
17
18
|
gemspec.authors = [ "Luca Guidi" ]
|
19
|
+
gemspec.executables = [ ]
|
18
20
|
end
|
19
21
|
|
20
22
|
Jeweler::GemcutterTasks.new
|
21
23
|
rescue LoadError
|
22
|
-
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
24
|
+
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
23
25
|
end
|
24
26
|
|
25
27
|
namespace :spec do
|
@@ -44,14 +46,26 @@ Spec::Rake::SpecTask.new(:rcov_run) do |t|
|
|
44
46
|
t.rcov = true
|
45
47
|
end
|
46
48
|
|
49
|
+
namespace :redis_cluster do
|
50
|
+
desc "Starts the redis_cluster"
|
51
|
+
task :start do
|
52
|
+
result = RedisClusterRunner.start_detached
|
53
|
+
raise("Could not start redis-server, aborting.") unless result
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "Stops the redis_cluster"
|
57
|
+
task :stop do
|
58
|
+
RedisClusterRunner.stop
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
47
62
|
# courtesy of http://github.com/ezmobius/redis-rb team
|
48
63
|
load "tasks/redis.tasks.rb"
|
49
64
|
def invoke_with_redis_cluster(task_name)
|
50
65
|
begin
|
51
|
-
|
52
|
-
raise("Could not start redis-server, aborting.") unless result
|
66
|
+
Rake::Task["redis_cluster:start"].invoke
|
53
67
|
Rake::Task[task_name].invoke
|
54
68
|
ensure
|
55
|
-
|
69
|
+
Rake::Task["redis_cluster:stop"].invoke
|
56
70
|
end
|
57
71
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.8
|
@@ -10,7 +10,7 @@ module Merb
|
|
10
10
|
# RedisStore.new :servers => ["example.com:23682/1"] # => host: example.com, port: 23682, db: 1
|
11
11
|
# RedisStore.new :servers => ["localhost:6379/0", "localhost:6380/0"] # => instantiate a cluster
|
12
12
|
def initialize(config = {})
|
13
|
-
@data =
|
13
|
+
@data = Redis::Factory.create config[:servers]
|
14
14
|
end
|
15
15
|
|
16
16
|
def writable?(key, parameters = {}, conditions = {})
|
@@ -18,12 +18,12 @@ module Merb
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def read(key, parameters = {}, conditions = {})
|
21
|
-
@data.
|
21
|
+
@data.marshalled_get normalize(key, parameters), conditions
|
22
22
|
end
|
23
23
|
|
24
24
|
def write(key, data = nil, parameters = {}, conditions = {})
|
25
25
|
if writable?(key, parameters, conditions)
|
26
|
-
method = conditions && conditions[:unless_exist] ? :
|
26
|
+
method = conditions && conditions[:unless_exist] ? :marshalled_setnx : :marshalled_set
|
27
27
|
@data.send method, normalize(key, parameters), data, conditions
|
28
28
|
end
|
29
29
|
end
|
@@ -37,15 +37,15 @@ module Merb
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def exists?(key, parameters = {})
|
40
|
-
@data.
|
40
|
+
@data.exists normalize(key, parameters)
|
41
41
|
end
|
42
42
|
|
43
43
|
def delete(key, parameters = {})
|
44
|
-
@data.
|
44
|
+
@data.del normalize(key, parameters)
|
45
45
|
end
|
46
46
|
|
47
47
|
def delete_all
|
48
|
-
@data.
|
48
|
+
@data.flushdb
|
49
49
|
end
|
50
50
|
|
51
51
|
def delete_all!
|
@@ -10,28 +10,28 @@ module ActiveSupport
|
|
10
10
|
# RedisStore.new "example.com:23682/1" # => host: example.com, port: 23682, db: 1
|
11
11
|
# RedisStore.new "localhost:6379/0", "localhost:6380/0" # => instantiate a cluster
|
12
12
|
def initialize(*addresses)
|
13
|
-
@data =
|
13
|
+
@data = Redis::Factory.create(addresses)
|
14
14
|
end
|
15
15
|
|
16
16
|
def write(key, value, options = nil)
|
17
17
|
super
|
18
|
-
method = options && options[:unless_exist] ? :
|
18
|
+
method = options && options[:unless_exist] ? :marshalled_setnx : :marshalled_set
|
19
19
|
@data.send method, key, value, options
|
20
20
|
end
|
21
21
|
|
22
22
|
def read(key, options = nil)
|
23
23
|
super
|
24
|
-
@data.
|
24
|
+
@data.marshalled_get key, options
|
25
25
|
end
|
26
26
|
|
27
27
|
def delete(key, options = nil)
|
28
28
|
super
|
29
|
-
@data.
|
29
|
+
@data.del key
|
30
30
|
end
|
31
31
|
|
32
32
|
def exist?(key, options = nil)
|
33
33
|
super
|
34
|
-
@data.
|
34
|
+
@data.exists key
|
35
35
|
end
|
36
36
|
|
37
37
|
# Increment a key in the store.
|
@@ -57,7 +57,7 @@ module ActiveSupport
|
|
57
57
|
# cache.read "rabbit", :raw => true # => "1"
|
58
58
|
def increment(key, amount = 1)
|
59
59
|
log "increment", key, amount
|
60
|
-
@data.
|
60
|
+
@data.incrby key, amount
|
61
61
|
end
|
62
62
|
|
63
63
|
# Decrement a key in the store
|
@@ -83,22 +83,22 @@ module ActiveSupport
|
|
83
83
|
# cache.read "rabbit", :raw => true # => "-1"
|
84
84
|
def decrement(key, amount = 1)
|
85
85
|
log "decrement", key, amount
|
86
|
-
@data.
|
86
|
+
@data.decrby key, amount
|
87
87
|
end
|
88
88
|
|
89
89
|
# Delete objects for matched keys.
|
90
90
|
#
|
91
91
|
# Example:
|
92
|
-
# cache.
|
92
|
+
# cache.del_matched "rab*"
|
93
93
|
def delete_matched(matcher, options = nil)
|
94
94
|
super
|
95
|
-
@data.keys(matcher).each { |key| @data.
|
95
|
+
@data.keys(matcher).each { |key| @data.del key }
|
96
96
|
end
|
97
97
|
|
98
98
|
# Clear all the data from the store.
|
99
99
|
def clear
|
100
100
|
log "clear", nil, nil
|
101
|
-
@data.
|
101
|
+
@data.flushdb
|
102
102
|
end
|
103
103
|
|
104
104
|
def stats
|
@@ -16,24 +16,27 @@ module Sinatra
|
|
16
16
|
# RedisStore.new "example.com:23682/1" # => host: example.com, port: 23682, db: 1
|
17
17
|
# RedisStore.new "localhost:6379/0", "localhost:6380/0" # => instantiate a cluster
|
18
18
|
def initialize(*addresses)
|
19
|
-
@data =
|
19
|
+
@data = Redis::Factory.create addresses
|
20
20
|
end
|
21
21
|
|
22
22
|
def write(key, value, options = nil)
|
23
|
-
|
24
|
-
|
23
|
+
if options && options[:unless_exist]
|
24
|
+
@data.marshalled_setnx key, value, options
|
25
|
+
else
|
26
|
+
@data.marshalled_set key, value, options
|
27
|
+
end
|
25
28
|
end
|
26
29
|
|
27
30
|
def read(key, options = nil)
|
28
|
-
@data.
|
31
|
+
@data.marshalled_get(key, options)
|
29
32
|
end
|
30
33
|
|
31
34
|
def delete(key, options = nil)
|
32
|
-
@data.
|
35
|
+
@data.del key
|
33
36
|
end
|
34
37
|
|
35
38
|
def exist?(key, options = nil)
|
36
|
-
@data.
|
39
|
+
@data.exists key
|
37
40
|
end
|
38
41
|
|
39
42
|
# Increment a key in the store.
|
@@ -58,7 +61,7 @@ module Sinatra
|
|
58
61
|
# cache.increment "rabbit"
|
59
62
|
# cache.read "rabbit", :raw => true # => "1"
|
60
63
|
def increment(key, amount = 1)
|
61
|
-
@data.
|
64
|
+
@data.incrby key, amount
|
62
65
|
end
|
63
66
|
|
64
67
|
# Decrement a key in the store
|
@@ -83,15 +86,15 @@ module Sinatra
|
|
83
86
|
# cache.decrement "rabbit"
|
84
87
|
# cache.read "rabbit", :raw => true # => "-1"
|
85
88
|
def decrement(key, amount = 1)
|
86
|
-
@data.
|
89
|
+
@data.decrby key, amount
|
87
90
|
end
|
88
91
|
|
89
92
|
# Delete objects for matched keys.
|
90
93
|
#
|
91
94
|
# Example:
|
92
|
-
# cache.
|
95
|
+
# cache.del_matched "rab*"
|
93
96
|
def delete_matched(matcher, options = nil)
|
94
|
-
@data.keys(matcher).each { |key| @data.
|
97
|
+
@data.keys(matcher).each { |key| @data.del key }
|
95
98
|
end
|
96
99
|
|
97
100
|
def fetch(key, options = {})
|
@@ -100,7 +103,7 @@ module Sinatra
|
|
100
103
|
|
101
104
|
# Clear all the data from the store.
|
102
105
|
def clear
|
103
|
-
@data.
|
106
|
+
@data.flushdb
|
104
107
|
end
|
105
108
|
|
106
109
|
def stats
|
@@ -4,7 +4,7 @@ module Rack
|
|
4
4
|
class RedisBase < MetaStore
|
5
5
|
extend Rack::Utils
|
6
6
|
|
7
|
-
# The ::
|
7
|
+
# The Redis::MarshaledClient object used to communicate with the Redis daemon.
|
8
8
|
attr_reader :cache
|
9
9
|
|
10
10
|
def self.resolve(uri)
|
@@ -17,21 +17,21 @@ module Rack
|
|
17
17
|
|
18
18
|
class Redis < RedisBase
|
19
19
|
def initialize(server, options = {})
|
20
|
-
@cache = ::
|
20
|
+
@cache = ::Redis::MarshaledClient.new server
|
21
21
|
end
|
22
22
|
|
23
23
|
def read(key)
|
24
24
|
key = hexdigest(key)
|
25
|
-
cache.
|
25
|
+
cache.marshalled_get(key) || []
|
26
26
|
end
|
27
27
|
|
28
28
|
def write(key, entries)
|
29
29
|
key = hexdigest(key)
|
30
|
-
cache.
|
30
|
+
cache.marshalled_set(key, entries)
|
31
31
|
end
|
32
32
|
|
33
33
|
def purge(key)
|
34
|
-
cache.
|
34
|
+
cache.del(hexdigest(key))
|
35
35
|
nil
|
36
36
|
end
|
37
37
|
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module ActionController
|
2
|
+
module Session
|
3
|
+
# Redis session storage for Rails, and for Rails only. Derived from
|
4
|
+
# the MemCacheStore code, simply dropping in Redis instead.
|
5
|
+
#
|
6
|
+
# Options:
|
7
|
+
# :key => Same as with the other cookie stores, key name
|
8
|
+
# :secret => Encryption secret for the key
|
9
|
+
# :host => Redis host name, default is localhost
|
10
|
+
# :port => Redis port, default is 6379
|
11
|
+
# :db => Database number, defaults to 0. Useful to separate your session storage from other data
|
12
|
+
# :key_prefix => Prefix for keys used in Redis, e.g. myapp-. Useful to separate session storage keys visibly from others
|
13
|
+
# :expire_after => A number in seconds to set the timeout interval for the session. Will map directly to expiry in Redis
|
14
|
+
|
15
|
+
class RedisSessionStore < ActionController::Session::AbstractStore
|
16
|
+
|
17
|
+
def initialize(app, options = {})
|
18
|
+
# Support old :expires option
|
19
|
+
options[:expire_after] ||= options[:expires]
|
20
|
+
|
21
|
+
super
|
22
|
+
|
23
|
+
@options = { :key_prefix => "" }.update(options)
|
24
|
+
servers = [options[:servers]].flatten.compact.map do |server_options|
|
25
|
+
{
|
26
|
+
:namespace => 'rack:session',
|
27
|
+
:host => 'localhost',
|
28
|
+
:port => '6379',
|
29
|
+
:db => 0
|
30
|
+
}.update(Redis::Factory.convert_to_redis_client_options(server_options))
|
31
|
+
end
|
32
|
+
|
33
|
+
@pool = Redis::Factory.create(*servers)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
def prefixed(sid)
|
38
|
+
"#{@options[:key_prefix]}#{sid}"
|
39
|
+
end
|
40
|
+
|
41
|
+
def get_session(env, sid)
|
42
|
+
sid ||= generate_sid
|
43
|
+
begin
|
44
|
+
session = @pool.marshalled_get(prefixed(sid)) || {}
|
45
|
+
rescue Errno::ECONNREFUSED
|
46
|
+
session = {}
|
47
|
+
end
|
48
|
+
[sid, session]
|
49
|
+
end
|
50
|
+
|
51
|
+
def set_session(env, sid, session_data)
|
52
|
+
options = env['rack.session.options']
|
53
|
+
@pool.marshalled_set(prefixed(sid), session_data, options)
|
54
|
+
return true
|
55
|
+
rescue Errno::ECONNREFUSED
|
56
|
+
return false
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
data/lib/rack/session/redis.rb
CHANGED
@@ -7,24 +7,24 @@ module Rack
|
|
7
7
|
def initialize(app, options = {})
|
8
8
|
super
|
9
9
|
@mutex = Mutex.new
|
10
|
-
@pool =
|
10
|
+
@pool = ::Redis::Factory.create options[:redis_server] || @default_options[:redis_server]
|
11
11
|
end
|
12
12
|
|
13
13
|
def generate_sid
|
14
14
|
loop do
|
15
15
|
sid = super
|
16
|
-
break sid unless @pool.
|
16
|
+
break sid unless @pool.marshalled_get(sid)
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
def get_session(env, sid)
|
21
|
-
session = @pool.
|
21
|
+
session = @pool.marshalled_get(sid) if sid
|
22
22
|
@mutex.lock if env['rack.multithread']
|
23
23
|
unless sid and session
|
24
24
|
env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
|
25
25
|
session = {}
|
26
26
|
sid = generate_sid
|
27
|
-
ret = @pool.
|
27
|
+
ret = @pool.marshalled_set sid, session
|
28
28
|
raise "Session collision on '#{sid.inspect}'" unless ret
|
29
29
|
end
|
30
30
|
session.instance_variable_set('@old', {}.merge(session))
|
@@ -39,16 +39,16 @@ module Rack
|
|
39
39
|
|
40
40
|
def set_session(env, session_id, new_session, options)
|
41
41
|
@mutex.lock if env['rack.multithread']
|
42
|
-
session = @pool.
|
42
|
+
session = @pool.marshalled_get(session_id) rescue {}
|
43
43
|
if options[:renew] or options[:drop]
|
44
|
-
@pool.
|
44
|
+
@pool.del session_id
|
45
45
|
return false if options[:drop]
|
46
46
|
session_id = generate_sid
|
47
|
-
@pool.
|
47
|
+
@pool.marshalled_set session_id, 0
|
48
48
|
end
|
49
49
|
old_session = new_session.instance_variable_get('@old') || {}
|
50
50
|
session = merge_sessions session_id, old_session, new_session, session
|
51
|
-
@pool.
|
51
|
+
@pool.marshalled_set session_id, session, options
|
52
52
|
return session_id
|
53
53
|
rescue Errno::ECONNREFUSED
|
54
54
|
warn "#{self} is unable to find server."
|
@@ -57,7 +57,7 @@ module Rack
|
|
57
57
|
ensure
|
58
58
|
@mutex.unlock if env['rack.multithread']
|
59
59
|
end
|
60
|
-
|
60
|
+
|
61
61
|
private
|
62
62
|
def merge_sessions(sid, old, new, cur=nil)
|
63
63
|
cur ||= {}
|
@@ -68,7 +68,7 @@ module Rack
|
|
68
68
|
|
69
69
|
delete = old.keys - new.keys
|
70
70
|
warn "//@#{sid}: dropping #{delete*','}" if $DEBUG and not delete.empty?
|
71
|
-
delete.each{|k| cur.
|
71
|
+
delete.each{|k| cur.del k }
|
72
72
|
|
73
73
|
update = new.keys.select{|k| new[k] != old[k] }
|
74
74
|
warn "//@#{sid}: updating #{update*','}" if $DEBUG and not update.empty?
|