redis-store 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of redis-store might be problematic. Click here for more details.

Files changed (39) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +13 -7
  3. data/README.md +11 -1
  4. data/Rakefile +19 -5
  5. data/VERSION +1 -1
  6. data/lib/cache/merb/redis_store.rb +6 -6
  7. data/lib/cache/rails/redis_store.rb +10 -10
  8. data/lib/cache/sinatra/redis_store.rb +14 -11
  9. data/lib/rack/cache/redis_entitystore.rb +2 -2
  10. data/lib/rack/cache/redis_metastore.rb +5 -5
  11. data/lib/rack/session/rails.rb +61 -0
  12. data/lib/rack/session/redis.rb +10 -10
  13. data/lib/redis-store.rb +8 -4
  14. data/lib/redis/distributed_marshaled.rb +18 -0
  15. data/lib/redis/factory.rb +26 -0
  16. data/lib/redis/marshaled_client.rb +54 -0
  17. data/lib/redis/namespace.rb +9 -0
  18. data/redis-store.gemspec +18 -13
  19. data/spec/cache/merb/redis_store_spec.rb +9 -14
  20. data/spec/cache/rails/redis_session_store_spec.rb +77 -0
  21. data/spec/cache/rails/redis_store_spec.rb +13 -17
  22. data/spec/cache/sinatra/redis_store_spec.rb +9 -14
  23. data/spec/config/master.conf +5 -5
  24. data/spec/config/single.conf +5 -5
  25. data/spec/config/slave.conf +6 -6
  26. data/spec/rack/cache/entitystore/redis_spec.rb +21 -11
  27. data/spec/rack/cache/metastore/redis_spec.rb +169 -16
  28. data/spec/rack/session/redis_spec.rb +7 -11
  29. data/spec/redis/distributed_marshaled_redis_spec.rb +9 -11
  30. data/spec/redis/factory_spec.rb +68 -0
  31. data/spec/redis/marshaled_client_spec.rb +54 -0
  32. data/spec/spec_helper.rb +11 -5
  33. data/tasks/redis.tasks.rb +16 -5
  34. metadata +28 -12
  35. data/lib/redis/distributed_marshaled_redis.rb +0 -10
  36. data/lib/redis/marshaled_redis.rb +0 -33
  37. data/lib/redis/redis_factory.rb +0 -27
  38. data/spec/redis/marshaled_redis_spec.rb +0 -54
  39. data/spec/redis/redis_factory_spec.rb +0 -34
data/.gitignore CHANGED
@@ -1,7 +1,11 @@
1
1
  *.rdb
2
2
  *.swp
3
+ *.gem
4
+ *-redis-store.gemspec
3
5
  bin/
4
6
  coverage/
5
7
  pkg/
6
8
  vendor/
7
9
  tmp/
10
+ .idea
11
+ .bundle/
data/Gemfile CHANGED
@@ -1,9 +1,15 @@
1
- # use ezmobius/redis-rb HEAD
2
- gem "redis-rb", "0.1", :git => "git://github.com/ezmobius/redis-rb.git"
1
+ source :gemcutter
2
+ gem "redis", "1.0.5"
3
3
 
4
4
  # testing gems
5
- gem "rspec", :only => :testing
6
- gem "rack-cache", :only => :testing
7
- gem "activesupport", :only => :testing
8
- gem "merb", :only => :testing
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
- Sorry, but Sinatra application boot system [hardcode](http://github.com/sinatra/sinatra/blob/0f02bafe86f8dd9bba9ab425468cb1067caa83ff/lib/sinatra/base.rb#L785) `Rack::Session::Cookie`
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
- result = RedisClusterRunner.start_detached
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
- RedisClusterRunner.stop
69
+ Rake::Task["redis_cluster:stop"].invoke
56
70
  end
57
71
  end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.7
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 = RedisFactory.create config[:servers]
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.get normalize(key, parameters), conditions
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] ? :set_unless_exists : :set
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.key? normalize(key, parameters)
40
+ @data.exists normalize(key, parameters)
41
41
  end
42
42
 
43
43
  def delete(key, parameters = {})
44
- @data.delete normalize(key, parameters)
44
+ @data.del normalize(key, parameters)
45
45
  end
46
46
 
47
47
  def delete_all
48
- @data.flush_db
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 = RedisFactory.create(addresses)
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] ? :set_unless_exists : :set
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.get key, options
24
+ @data.marshalled_get key, options
25
25
  end
26
26
 
27
27
  def delete(key, options = nil)
28
28
  super
29
- @data.delete key
29
+ @data.del key
30
30
  end
31
31
 
32
32
  def exist?(key, options = nil)
33
33
  super
34
- @data.key? key
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.incr key, amount
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.decr key, amount
86
+ @data.decrby key, amount
87
87
  end
88
88
 
89
89
  # Delete objects for matched keys.
90
90
  #
91
91
  # Example:
92
- # cache.delete_matched "rab*"
92
+ # cache.del_matched "rab*"
93
93
  def delete_matched(matcher, options = nil)
94
94
  super
95
- @data.keys(matcher).each { |key| @data.delete key }
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.flush_db
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 = RedisFactory.create addresses
19
+ @data = Redis::Factory.create addresses
20
20
  end
21
21
 
22
22
  def write(key, value, options = nil)
23
- method = options && options[:unless_exist] ? :set_unless_exists : :set
24
- @data.send method, key, value, options
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.get key, options
31
+ @data.marshalled_get(key, options)
29
32
  end
30
33
 
31
34
  def delete(key, options = nil)
32
- @data.delete key
35
+ @data.del key
33
36
  end
34
37
 
35
38
  def exist?(key, options = nil)
36
- @data.key? key
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.incr key, amount
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.decr key, amount
89
+ @data.decrby key, amount
87
90
  end
88
91
 
89
92
  # Delete objects for matched keys.
90
93
  #
91
94
  # Example:
92
- # cache.delete_matched "rab*"
95
+ # cache.del_matched "rab*"
93
96
  def delete_matched(matcher, options = nil)
94
- @data.keys(matcher).each { |key| @data.delete key }
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.flush_db
106
+ @data.flushdb
104
107
  end
105
108
 
106
109
  def stats
@@ -26,7 +26,7 @@ module Rack
26
26
  end
27
27
 
28
28
  def exist?(key)
29
- cache.key? key
29
+ cache.exists key
30
30
  end
31
31
 
32
32
  def read(key)
@@ -40,7 +40,7 @@ module Rack
40
40
  end
41
41
 
42
42
  def purge(key)
43
- cache.delete key
43
+ cache.del key
44
44
  nil
45
45
  end
46
46
  end
@@ -4,7 +4,7 @@ module Rack
4
4
  class RedisBase < MetaStore
5
5
  extend Rack::Utils
6
6
 
7
- # The ::MarshaledRedis object used to communicate with the Redis daemon.
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 = ::MarshaledRedis.new server
20
+ @cache = ::Redis::MarshaledClient.new server
21
21
  end
22
22
 
23
23
  def read(key)
24
24
  key = hexdigest(key)
25
- cache.get(key) || []
25
+ cache.marshalled_get(key) || []
26
26
  end
27
27
 
28
28
  def write(key, entries)
29
29
  key = hexdigest(key)
30
- cache.set(key, entries)
30
+ cache.marshalled_set(key, entries)
31
31
  end
32
32
 
33
33
  def purge(key)
34
- cache.delete(hexdigest(key))
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
@@ -7,24 +7,24 @@ module Rack
7
7
  def initialize(app, options = {})
8
8
  super
9
9
  @mutex = Mutex.new
10
- @pool = RedisFactory.create options[:redis_server] || @default_options[:redis_server]
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.get(sid)
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.get(sid) if sid
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.set sid, session
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.get(session_id) rescue {}
42
+ session = @pool.marshalled_get(session_id) rescue {}
43
43
  if options[:renew] or options[:drop]
44
- @pool.delete session_id
44
+ @pool.del session_id
45
45
  return false if options[:drop]
46
46
  session_id = generate_sid
47
- @pool.set session_id, 0
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.set session_id, session, options
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.delete k }
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?