redis-store 1.0.0.beta2 → 1.0.0.beta3
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/CHANGELOG +74 -23
- data/Gemfile +12 -7
- data/Gemfile.lock +183 -0
- data/MIT-LICENSE +1 -1
- data/README.md +49 -14
- data/Rakefile +8 -4
- data/VERSION +1 -1
- data/lib/{rack/session/rails.rb → action_controller/session/redis_session_store.rb} +24 -20
- data/lib/{cache/rails → active_support/cache}/redis_store.rb +64 -22
- data/lib/cache/merb/redis_store.rb +20 -8
- data/lib/cache/sinatra/redis_store.rb +20 -8
- data/lib/i18n/backend/redis.rb +67 -0
- data/lib/rack/cache/redis_metastore.rb +4 -4
- data/lib/rack/session/redis.rb +7 -7
- data/lib/redis-store.rb +16 -14
- data/lib/redis/distributed_store.rb +35 -0
- data/lib/redis/factory.rb +29 -10
- data/lib/redis/store.rb +30 -0
- data/lib/redis/store/interface.rb +17 -0
- data/lib/redis/store/marshalling.rb +41 -0
- data/lib/redis/store/namespace.rb +54 -0
- data/lib/redis/store/ttl.rb +37 -0
- data/lib/redis/store/version.rb +12 -0
- data/redis-store.gemspec +32 -20
- data/spec/action_controller/session/redis_session_store_spec.rb +121 -0
- data/spec/{cache/rails → active_support/cache}/redis_store_spec.rb +93 -19
- data/spec/cache/merb/redis_store_spec.rb +14 -11
- data/spec/cache/sinatra/redis_store_spec.rb +14 -11
- data/spec/config/master.conf +1 -1
- data/spec/config/single.conf +1 -1
- data/spec/config/slave.conf +1 -1
- data/spec/i18n/backend/redis_spec.rb +56 -0
- data/spec/rack/cache/entitystore/redis_spec.rb +10 -8
- data/spec/rack/cache/metastore/redis_spec.rb +2 -2
- data/spec/rack/session/redis_spec.rb +6 -6
- data/spec/redis/distributed_store_spec.rb +47 -0
- data/spec/redis/factory_spec.rb +58 -16
- data/spec/redis/store/interface_spec.rb +23 -0
- data/spec/redis/store/marshalling_spec.rb +83 -0
- data/spec/redis/store/namespace_spec.rb +76 -0
- data/spec/redis/store/version_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -5
- data/tasks/redis.tasks.rb +19 -12
- metadata +33 -21
- data/lib/redis/distributed_marshaled.rb +0 -28
- data/lib/redis/marshaled_client.rb +0 -65
- data/lib/redis_store/version.rb +0 -10
- data/spec/rack/session/redis_session_store_spec.rb +0 -75
- data/spec/redis/distributed_marshaled_redis_spec.rb +0 -33
- data/spec/redis/marshaled_client_spec.rb +0 -83
- data/spec/redis_store/version_spec.rb +0 -7
data/Rakefile
CHANGED
@@ -11,8 +11,8 @@ begin
|
|
11
11
|
require "jeweler"
|
12
12
|
Jeweler::Tasks.new do |gemspec|
|
13
13
|
gemspec.name = "#{ENV["GEM_PREFIX"]}redis-store"
|
14
|
-
gemspec.summary = "Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks."
|
15
|
-
gemspec.description = "Rack::Session, Rack::Cache and cache Redis stores for Ruby web frameworks."
|
14
|
+
gemspec.summary = "Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks."
|
15
|
+
gemspec.description = "Namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks."
|
16
16
|
gemspec.email = "guidi.luca@gmail.com"
|
17
17
|
gemspec.homepage = "http://github.com/jodosha/redis-store"
|
18
18
|
gemspec.authors = [ "Luca Guidi" ]
|
@@ -27,7 +27,7 @@ end
|
|
27
27
|
|
28
28
|
namespace :spec do
|
29
29
|
desc "Run all the examples by starting a detached Redis instance"
|
30
|
-
task :suite do
|
30
|
+
task :suite => :prepare do
|
31
31
|
invoke_with_redis_cluster "spec:run"
|
32
32
|
end
|
33
33
|
|
@@ -38,7 +38,7 @@ namespace :spec do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
desc "Run all examples with RCov"
|
41
|
-
task :rcov do
|
41
|
+
task :rcov => :prepare do
|
42
42
|
invoke_with_redis_cluster "rcov_run"
|
43
43
|
end
|
44
44
|
|
@@ -47,6 +47,10 @@ Spec::Rake::SpecTask.new(:rcov_run) do |t|
|
|
47
47
|
t.rcov = true
|
48
48
|
end
|
49
49
|
|
50
|
+
task :prepare do
|
51
|
+
`mkdir -p tmp && rm tmp/*.rdb`
|
52
|
+
end
|
53
|
+
|
50
54
|
namespace :bundle do
|
51
55
|
task :clean do
|
52
56
|
system "rm -rf ~/.bundle/ ~/.gem/ .bundle/ Gemfile.lock"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.0.
|
1
|
+
1.0.0.beta3
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require "redis-store"
|
2
|
+
|
1
3
|
module RedisStore
|
2
4
|
module Rack
|
3
5
|
module Session
|
@@ -19,10 +21,8 @@ module RedisStore
|
|
19
21
|
|
20
22
|
super
|
21
23
|
|
22
|
-
@options = { :key_prefix => "" }.update(options)
|
23
24
|
servers = [options[:servers]].flatten.compact.map do |server_options|
|
24
25
|
{
|
25
|
-
:namespace => 'rack:session',
|
26
26
|
:host => 'localhost',
|
27
27
|
:port => '6379',
|
28
28
|
:db => 0
|
@@ -33,33 +33,37 @@ module RedisStore
|
|
33
33
|
end
|
34
34
|
|
35
35
|
private
|
36
|
-
|
37
|
-
|
38
|
-
|
36
|
+
def get_session(env, sid)
|
37
|
+
sid ||= generate_sid
|
38
|
+
begin
|
39
|
+
session = @pool.get(sid) || {}
|
40
|
+
rescue Errno::ECONNREFUSED
|
41
|
+
session = {}
|
42
|
+
end
|
43
|
+
[sid, session]
|
44
|
+
end
|
39
45
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
46
|
+
def set_session(env, sid, session_data)
|
47
|
+
options = env['rack.session.options']
|
48
|
+
@pool.set(sid, session_data, options)
|
49
|
+
return true
|
44
50
|
rescue Errno::ECONNREFUSED
|
45
|
-
|
51
|
+
return false
|
46
52
|
end
|
47
|
-
[sid, session]
|
48
|
-
end
|
49
53
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
54
|
+
def destroy(env)
|
55
|
+
if sid = current_session_id(env)
|
56
|
+
@pool.del(sid)
|
57
|
+
end
|
58
|
+
rescue Errno::ECONNREFUSED
|
59
|
+
false
|
60
|
+
end
|
57
61
|
end
|
58
62
|
end
|
59
63
|
end
|
60
64
|
end
|
61
65
|
|
62
|
-
if ::
|
66
|
+
if ::Redis::Store.rails3?
|
63
67
|
class ActionDispatch::Session::RedisSessionStore < ActionDispatch::Session::AbstractStore
|
64
68
|
include RedisStore::Rack::Session::Rails
|
65
69
|
end
|
@@ -1,15 +1,17 @@
|
|
1
|
+
require "redis-store"
|
2
|
+
|
1
3
|
module ::RedisStore
|
2
4
|
module Cache
|
3
5
|
module Rails2
|
4
6
|
def write(key, value, options = nil)
|
5
7
|
super
|
6
|
-
method = options && options[:unless_exist] ? :
|
8
|
+
method = options && options[:unless_exist] ? :setnx : :set
|
7
9
|
@data.send method, key, value, options
|
8
10
|
end
|
9
11
|
|
10
12
|
def read(key, options = nil)
|
11
13
|
super
|
12
|
-
@data.
|
14
|
+
@data.get key, options
|
13
15
|
end
|
14
16
|
|
15
17
|
def delete(key, options = nil)
|
@@ -22,6 +24,16 @@ module ::RedisStore
|
|
22
24
|
@data.exists key
|
23
25
|
end
|
24
26
|
|
27
|
+
# Delete objects for matched keys.
|
28
|
+
#
|
29
|
+
# Example:
|
30
|
+
# cache.del_matched "rab*"
|
31
|
+
def delete_matched(matcher, options = nil)
|
32
|
+
instrument(:delete_matched, matcher, options) do
|
33
|
+
@data.keys(matcher).each { |key| @data.del key }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
25
37
|
private
|
26
38
|
def instrument(operation, key, options = nil)
|
27
39
|
log(operation.to_s, key, options)
|
@@ -30,14 +42,26 @@ module ::RedisStore
|
|
30
42
|
end
|
31
43
|
|
32
44
|
module Rails3
|
45
|
+
# Delete objects for matched keys.
|
46
|
+
#
|
47
|
+
# Example:
|
48
|
+
# cache.del_matched "rab*"
|
49
|
+
def delete_matched(matcher, options = nil)
|
50
|
+
options = merged_options(options)
|
51
|
+
instrument(:delete_matched, matcher.inspect) do
|
52
|
+
matcher = key_matcher(matcher, options)
|
53
|
+
@data.keys(matcher).each { |key| delete_entry(key, options) }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
33
57
|
protected
|
34
58
|
def write_entry(key, entry, options)
|
35
|
-
method = options && options[:unless_exist] ? :
|
59
|
+
method = options && options[:unless_exist] ? :setnx : :set
|
36
60
|
@data.send method, key, entry, options
|
37
61
|
end
|
38
62
|
|
39
63
|
def read_entry(key, options)
|
40
|
-
entry = @data.
|
64
|
+
entry = @data.get key, options
|
41
65
|
if entry
|
42
66
|
entry.is_a?(ActiveSupport::Cache::Entry) ? entry : ActiveSupport::Cache::Entry.new(entry)
|
43
67
|
end
|
@@ -46,10 +70,25 @@ module ::RedisStore
|
|
46
70
|
def delete_entry(key, options)
|
47
71
|
@data.del key
|
48
72
|
end
|
73
|
+
|
74
|
+
# Add the namespace defined in the options to a pattern designed to match keys.
|
75
|
+
#
|
76
|
+
# This implementation is __different__ than ActiveSupport:
|
77
|
+
# __it doesn't accept Regular expressions__, because the Redis matcher is designed
|
78
|
+
# only for strings with wildcards.
|
79
|
+
def key_matcher(pattern, options)
|
80
|
+
prefix = options[:namespace].is_a?(Proc) ? options[:namespace].call : options[:namespace]
|
81
|
+
if prefix
|
82
|
+
raise "Regexps aren't supported, please use string with wildcards." if pattern.is_a?(Regexp)
|
83
|
+
"#{prefix}:#{pattern}"
|
84
|
+
else
|
85
|
+
pattern
|
86
|
+
end
|
87
|
+
end
|
49
88
|
end
|
50
89
|
|
51
90
|
module Store
|
52
|
-
include ::
|
91
|
+
include ::Redis::Store.rails3? ? Rails3 : Rails2
|
53
92
|
end
|
54
93
|
end
|
55
94
|
end
|
@@ -62,23 +101,26 @@ module ActiveSupport
|
|
62
101
|
# Instantiate the store.
|
63
102
|
#
|
64
103
|
# Example:
|
65
|
-
# RedisStore.new
|
66
|
-
#
|
67
|
-
# RedisStore.new "example.com:23682" # => host: example.com, port: 23682, db: 0
|
68
|
-
# RedisStore.new "example.com:23682/1" # => host: example.com, port: 23682, db: 1
|
69
|
-
# RedisStore.new "localhost:6379/0", "localhost:6380/0" # => instantiate a cluster
|
70
|
-
def initialize(*addresses)
|
71
|
-
@data = Redis::Factory.create(addresses)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Delete objects for matched keys.
|
104
|
+
# RedisStore.new
|
105
|
+
# # => host: localhost, port: 6379, db: 0
|
75
106
|
#
|
76
|
-
#
|
77
|
-
#
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
107
|
+
# RedisStore.new "example.com"
|
108
|
+
# # => host: example.com, port: 6379, db: 0
|
109
|
+
#
|
110
|
+
# RedisStore.new "example.com:23682"
|
111
|
+
# # => host: example.com, port: 23682, db: 0
|
112
|
+
#
|
113
|
+
# RedisStore.new "example.com:23682/1"
|
114
|
+
# # => host: example.com, port: 23682, db: 1
|
115
|
+
#
|
116
|
+
# RedisStore.new "example.com:23682/1/theplaylist"
|
117
|
+
# # => host: example.com, port: 23682, db: 1, namespace: theplaylist
|
118
|
+
#
|
119
|
+
# RedisStore.new "localhost:6379/0", "localhost:6380/0"
|
120
|
+
# # => instantiate a cluster
|
121
|
+
def initialize(*addresses)
|
122
|
+
@data = ::Redis::Factory.create(addresses)
|
123
|
+
super(addresses.extract_options!)
|
82
124
|
end
|
83
125
|
|
84
126
|
# Reads multiple keys from the cache using a single call to the
|
@@ -88,7 +130,7 @@ module ActiveSupport
|
|
88
130
|
# cache.read_multi "rabbit", "white-rabbit"
|
89
131
|
# cache.read_multi "rabbit", "white-rabbit", :raw => true
|
90
132
|
def read_multi(*names)
|
91
|
-
@data.
|
133
|
+
@data.mget *names
|
92
134
|
end
|
93
135
|
|
94
136
|
# Increment a key in the store.
|
@@ -4,12 +4,24 @@ module Merb
|
|
4
4
|
# Instantiate the store.
|
5
5
|
#
|
6
6
|
# Example:
|
7
|
-
# RedisStore.new
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# RedisStore.new :servers => ["example.com
|
11
|
-
#
|
12
|
-
|
7
|
+
# RedisStore.new
|
8
|
+
# # => host: localhost, port: 6379, db: 0
|
9
|
+
#
|
10
|
+
# RedisStore.new :servers => ["example.com"]
|
11
|
+
# # => host: example.com, port: 6379, db: 0
|
12
|
+
#
|
13
|
+
# RedisStore.new :servers => ["example.com:23682"]
|
14
|
+
# # => host: example.com, port: 23682, db: 0
|
15
|
+
#
|
16
|
+
# RedisStore.new :servers => ["example.com:23682/1"]
|
17
|
+
# # => host: example.com, port: 23682, db: 1
|
18
|
+
#
|
19
|
+
# RedisStore.new :servers => ["example.com:23682/1/theplaylist"]
|
20
|
+
# # => host: example.com, port: 23682, db: 1, namespace: theplaylist
|
21
|
+
#
|
22
|
+
# RedisStore.new :servers => ["localhost:6379/0", "localhost:6380/0"]
|
23
|
+
# # => instantiate a cluster
|
24
|
+
def initialize(config = { })
|
13
25
|
@data = Redis::Factory.create config[:servers]
|
14
26
|
end
|
15
27
|
|
@@ -18,12 +30,12 @@ module Merb
|
|
18
30
|
end
|
19
31
|
|
20
32
|
def read(key, parameters = {}, conditions = {})
|
21
|
-
@data.
|
33
|
+
@data.get normalize(key, parameters), conditions
|
22
34
|
end
|
23
35
|
|
24
36
|
def write(key, data = nil, parameters = {}, conditions = {})
|
25
37
|
if writable?(key, parameters, conditions)
|
26
|
-
method = conditions && conditions[:unless_exist] ? :
|
38
|
+
method = conditions && conditions[:unless_exist] ? :setnx : :set
|
27
39
|
@data.send method, normalize(key, parameters), data, conditions
|
28
40
|
end
|
29
41
|
end
|
@@ -10,25 +10,37 @@ module Sinatra
|
|
10
10
|
# Instantiate the store.
|
11
11
|
#
|
12
12
|
# Example:
|
13
|
-
# RedisStore.new
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# RedisStore.new "example.com
|
17
|
-
#
|
13
|
+
# RedisStore.new
|
14
|
+
# # => host: localhost, port: 6379, db: 0
|
15
|
+
#
|
16
|
+
# RedisStore.new "example.com"
|
17
|
+
# # => host: example.com, port: 6379, db: 0
|
18
|
+
#
|
19
|
+
# RedisStore.new "example.com:23682"
|
20
|
+
# # => host: example.com, port: 23682, db: 0
|
21
|
+
#
|
22
|
+
# RedisStore.new "example.com:23682/1"
|
23
|
+
# # => host: example.com, port: 23682, db: 1
|
24
|
+
#
|
25
|
+
# RedisStore.new "example.com:23682/1/theplaylist"
|
26
|
+
# # => host: example.com, port: 23682, db: 1, namespace: theplaylist
|
27
|
+
#
|
28
|
+
# RedisStore.new "localhost:6379/0", "localhost:6380/0"
|
29
|
+
# # => instantiate a cluster
|
18
30
|
def initialize(*addresses)
|
19
31
|
@data = Redis::Factory.create addresses
|
20
32
|
end
|
21
33
|
|
22
34
|
def write(key, value, options = nil)
|
23
35
|
if options && options[:unless_exist]
|
24
|
-
@data.
|
36
|
+
@data.setnx key, value, options
|
25
37
|
else
|
26
|
-
@data.
|
38
|
+
@data.set key, value, options
|
27
39
|
end
|
28
40
|
end
|
29
41
|
|
30
42
|
def read(key, options = nil)
|
31
|
-
@data.
|
43
|
+
@data.get(key, options)
|
32
44
|
end
|
33
45
|
|
34
46
|
def delete(key, options = nil)
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module I18n
|
2
|
+
module Backend
|
3
|
+
class Redis
|
4
|
+
include Base, Flatten
|
5
|
+
attr_accessor :store
|
6
|
+
|
7
|
+
# Instantiate the store.
|
8
|
+
#
|
9
|
+
# Example:
|
10
|
+
# RedisStore.new
|
11
|
+
# # => host: localhost, port: 6379, db: 0
|
12
|
+
#
|
13
|
+
# RedisStore.new "example.com"
|
14
|
+
# # => host: example.com, port: 6379, db: 0
|
15
|
+
#
|
16
|
+
# RedisStore.new "example.com:23682"
|
17
|
+
# # => host: example.com, port: 23682, db: 0
|
18
|
+
#
|
19
|
+
# RedisStore.new "example.com:23682/1"
|
20
|
+
# # => host: example.com, port: 23682, db: 1
|
21
|
+
#
|
22
|
+
# RedisStore.new "example.com:23682/1/theplaylist"
|
23
|
+
# # => host: example.com, port: 23682, db: 1, namespace: theplaylist
|
24
|
+
#
|
25
|
+
# RedisStore.new "localhost:6379/0", "localhost:6380/0"
|
26
|
+
# # => instantiate a cluster
|
27
|
+
def initialize(*addresses)
|
28
|
+
@store = ::Redis::Factory.create(addresses)
|
29
|
+
end
|
30
|
+
|
31
|
+
def translate(locale, key, options = {})
|
32
|
+
options[:resolve] ||= false
|
33
|
+
super locale, key, options
|
34
|
+
end
|
35
|
+
|
36
|
+
def store_translations(locale, data, options = {})
|
37
|
+
escape = options.fetch(:escape, true)
|
38
|
+
flatten_translations(locale, data, escape, false).each do |key, value|
|
39
|
+
case value
|
40
|
+
when Proc
|
41
|
+
raise "Key-value stores cannot handle procs"
|
42
|
+
else
|
43
|
+
@store.set "#{locale}.#{key}", value
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def available_locales
|
49
|
+
locales = @store.keys.map { |k| k =~ /\./; $` }
|
50
|
+
locales.uniq!
|
51
|
+
locales.compact!
|
52
|
+
locales.map! { |k| k.to_sym }
|
53
|
+
locales
|
54
|
+
end
|
55
|
+
|
56
|
+
protected
|
57
|
+
def lookup(locale, key, scope = [], options = {})
|
58
|
+
key = normalize_flat_keys(locale, key, scope, options[:separator])
|
59
|
+
@store.get "#{locale}.#{key}"
|
60
|
+
end
|
61
|
+
|
62
|
+
def resolve_link(locale, key)
|
63
|
+
key
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -4,7 +4,7 @@ module Rack
|
|
4
4
|
class RedisBase < MetaStore
|
5
5
|
extend Rack::Utils
|
6
6
|
|
7
|
-
# The Redis::
|
7
|
+
# The Redis::Store object used to communicate with the Redis daemon.
|
8
8
|
attr_reader :cache
|
9
9
|
|
10
10
|
def self.resolve(uri)
|
@@ -17,17 +17,17 @@ module Rack
|
|
17
17
|
|
18
18
|
class Redis < RedisBase
|
19
19
|
def initialize(server, options = {})
|
20
|
-
@cache = ::Redis::
|
20
|
+
@cache = ::Redis::Factory.create server
|
21
21
|
end
|
22
22
|
|
23
23
|
def read(key)
|
24
24
|
key = hexdigest(key)
|
25
|
-
cache.
|
25
|
+
cache.get(key) || []
|
26
26
|
end
|
27
27
|
|
28
28
|
def write(key, entries)
|
29
29
|
key = hexdigest(key)
|
30
|
-
cache.
|
30
|
+
cache.set(key, entries)
|
31
31
|
end
|
32
32
|
|
33
33
|
def purge(key)
|