redis-store 1.0.0.beta2 → 1.0.0.beta3

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 (51) hide show
  1. data/CHANGELOG +74 -23
  2. data/Gemfile +12 -7
  3. data/Gemfile.lock +183 -0
  4. data/MIT-LICENSE +1 -1
  5. data/README.md +49 -14
  6. data/Rakefile +8 -4
  7. data/VERSION +1 -1
  8. data/lib/{rack/session/rails.rb → action_controller/session/redis_session_store.rb} +24 -20
  9. data/lib/{cache/rails → active_support/cache}/redis_store.rb +64 -22
  10. data/lib/cache/merb/redis_store.rb +20 -8
  11. data/lib/cache/sinatra/redis_store.rb +20 -8
  12. data/lib/i18n/backend/redis.rb +67 -0
  13. data/lib/rack/cache/redis_metastore.rb +4 -4
  14. data/lib/rack/session/redis.rb +7 -7
  15. data/lib/redis-store.rb +16 -14
  16. data/lib/redis/distributed_store.rb +35 -0
  17. data/lib/redis/factory.rb +29 -10
  18. data/lib/redis/store.rb +30 -0
  19. data/lib/redis/store/interface.rb +17 -0
  20. data/lib/redis/store/marshalling.rb +41 -0
  21. data/lib/redis/store/namespace.rb +54 -0
  22. data/lib/redis/store/ttl.rb +37 -0
  23. data/lib/redis/store/version.rb +12 -0
  24. data/redis-store.gemspec +32 -20
  25. data/spec/action_controller/session/redis_session_store_spec.rb +121 -0
  26. data/spec/{cache/rails → active_support/cache}/redis_store_spec.rb +93 -19
  27. data/spec/cache/merb/redis_store_spec.rb +14 -11
  28. data/spec/cache/sinatra/redis_store_spec.rb +14 -11
  29. data/spec/config/master.conf +1 -1
  30. data/spec/config/single.conf +1 -1
  31. data/spec/config/slave.conf +1 -1
  32. data/spec/i18n/backend/redis_spec.rb +56 -0
  33. data/spec/rack/cache/entitystore/redis_spec.rb +10 -8
  34. data/spec/rack/cache/metastore/redis_spec.rb +2 -2
  35. data/spec/rack/session/redis_spec.rb +6 -6
  36. data/spec/redis/distributed_store_spec.rb +47 -0
  37. data/spec/redis/factory_spec.rb +58 -16
  38. data/spec/redis/store/interface_spec.rb +23 -0
  39. data/spec/redis/store/marshalling_spec.rb +83 -0
  40. data/spec/redis/store/namespace_spec.rb +76 -0
  41. data/spec/redis/store/version_spec.rb +7 -0
  42. data/spec/spec_helper.rb +16 -5
  43. data/tasks/redis.tasks.rb +19 -12
  44. metadata +33 -21
  45. data/lib/redis/distributed_marshaled.rb +0 -28
  46. data/lib/redis/marshaled_client.rb +0 -65
  47. data/lib/redis_store/version.rb +0 -10
  48. data/spec/rack/session/redis_session_store_spec.rb +0 -75
  49. data/spec/redis/distributed_marshaled_redis_spec.rb +0 -33
  50. data/spec/redis/marshaled_client_spec.rb +0 -83
  51. data/spec/redis_store/version_spec.rb +0 -7
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "/../../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  class Object
4
4
  def sha_like?
@@ -92,13 +92,15 @@ module Rack
92
92
  @store.open('87fe0a1ae82a518592f6b12b0183e950b4541c62').should be_nil
93
93
  end
94
94
 
95
- it 'can store largish bodies with binary data' do
96
- pony = ::File.open(::File.dirname(__FILE__) + '/pony.jpg', 'rb') { |f| f.read }
97
- key, size = @store.write([pony])
98
- key.should == 'd0f30d8659b4d268c5c64385d9790024c2d78deb'
99
- data = @store.read(key)
100
- data.length.should == pony.length
101
- data.hash.should == pony.hash
95
+ if RUBY_VERSION < '1.9'
96
+ it 'can store largish bodies with binary data' do
97
+ pony = ::File.open(::File.dirname(__FILE__) + '/pony.jpg', 'rb') { |f| f.read }
98
+ key, size = @store.write([pony])
99
+ key.should == 'd0f30d8659b4d268c5c64385d9790024c2d78deb'
100
+ data = @store.read(key)
101
+ data.length.should == pony.length
102
+ data.hash.should == pony.hash
103
+ end
102
104
  end
103
105
 
104
106
  it 'deletes stored entries with #purge' do
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "/../../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  module Rack
4
4
  module Cache
@@ -23,7 +23,7 @@ module Rack
23
23
 
24
24
  it "should resolve the connection uri" do
25
25
  cache = Rack::Cache::MetaStore::Redis.resolve(uri("redis://127.0.0.1")).cache
26
- cache.should be_kind_of(::Redis::MarshaledClient)
26
+ cache.should be_kind_of(::Redis::Store)
27
27
  cache.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
28
28
 
29
29
  cache = Rack::Cache::MetaStore::Redis.resolve(uri("redis://127.0.0.1:6380")).cache
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "/../../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  module Rack
4
4
  module Session
@@ -26,12 +26,12 @@ module Rack
26
26
  end
27
27
 
28
28
  it "should specify connection params" do
29
- pool = Rack::Session::Redis.new(@incrementor, :redis_server => "localhost:6380/1").pool
30
- pool.should be_kind_of(::Redis::MarshaledClient)
31
- pool.to_s.should == "Redis Client connected to localhost:6380 against DB 1"
29
+ pool = Rack::Session::Redis.new(@incrementor, :redis_server => "redis://127.0.0.1:6380/1/theplaylist").pool
30
+ pool.should be_kind_of(::Redis::Store)
31
+ pool.to_s.should == "Redis Client connected to 127.0.0.1:6380 against DB 1 with namespace theplaylist"
32
32
 
33
- pool = Rack::Session::Redis.new(@incrementor, :redis_server => ["localhost:6379", "localhost:6380"]).pool
34
- pool.should be_kind_of(::Redis::DistributedMarshaled)
33
+ pool = Rack::Session::Redis.new(@incrementor, :redis_server => ["redis://127.0.0.1:6379", "redis://127.0.0.1:6380"]).pool
34
+ pool.should be_kind_of(::Redis::DistributedStore)
35
35
  end
36
36
 
37
37
  it "creates a new cookie" do
@@ -0,0 +1,47 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Redis::DistributedStore" do
4
+ before(:each) do
5
+ @dmr = Redis::DistributedStore.new [
6
+ {:host => "localhost", :port => "6380", :db => 0},
7
+ {:host => "localhost", :port => "6381", :db => 0}
8
+ ]
9
+ @rabbit = OpenStruct.new :name => "bunny"
10
+ @white_rabbit = OpenStruct.new :color => "white"
11
+ @dmr.set "rabbit", @rabbit
12
+ end
13
+
14
+ after(:all) do
15
+ @dmr.ring.nodes.each { |server| server.flushdb }
16
+ end
17
+
18
+ it "should accept connection params" do
19
+ dmr = Redis::DistributedStore.new [ :host => "localhost", :port => "6380", :db => "1" ]
20
+ dmr.ring.nodes.size == 1
21
+ mr = dmr.ring.nodes.first
22
+ mr.to_s.should == "Redis Client connected to localhost:6380 against DB 1"
23
+ end
24
+
25
+ it "should set an object" do
26
+ @dmr.set "rabbit", @white_rabbit
27
+ @dmr.get("rabbit").should == @white_rabbit
28
+ end
29
+
30
+ it "should get an object" do
31
+ @dmr.get("rabbit").should == @rabbit
32
+ end
33
+
34
+ describe "namespace" do
35
+ before :each do
36
+ @dmr = Redis::DistributedStore.new [
37
+ {:host => "localhost", :port => "6380", :db => 0},
38
+ {:host => "localhost", :port => "6381", :db => 0}
39
+ ], :namespace => "theplaylist"
40
+ end
41
+
42
+ it "should use namespaced key" do
43
+ @dmr.should_receive(:node_for).with("theplaylist:rabbit").and_return @dmr.nodes.first
44
+ @dmr.get "rabbit"
45
+ end
46
+ end
47
+ end
@@ -1,11 +1,11 @@
1
- require File.join(File.dirname(__FILE__), "/../spec_helper")
1
+ require 'spec_helper'
2
2
 
3
3
  describe "Redis::Factory" do
4
4
  describe ".create" do
5
5
  context "when not given any arguments" do
6
- it "should instantiate a Redis::MarshaledClient store" do
6
+ it "should instantiate a Redis::Store store" do
7
7
  store = Redis::Factory.create
8
- store.should be_kind_of(Redis::MarshaledClient)
8
+ store.should be_kind_of(Redis::Store)
9
9
  store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
10
10
  end
11
11
  end
@@ -26,12 +26,32 @@ describe "Redis::Factory" do
26
26
  store.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
27
27
  end
28
28
 
29
- it "should instantiate a Redis::DistributedMarshaled store" do
29
+ it "should allow to specify namespace" do
30
+ store = Redis::Factory.create :namespace => "theplaylist"
31
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist"
32
+ end
33
+
34
+ it "should allow to specify key_prefix as namespace" do
35
+ store = Redis::Factory.create :key_prefix => "theplaylist"
36
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist"
37
+ end
38
+
39
+ it "should allow to specify marshalling" do
40
+ store = Redis::Factory.create :marshalling => false
41
+ store.instance_variable_get(:@marshalling).should be_false
42
+ end
43
+
44
+ it "should allow to specify password" do
45
+ store = Redis::Factory.create :password => "secret"
46
+ store.instance_variable_get(:@client).password.should == "secret"
47
+ end
48
+
49
+ it "should instantiate a Redis::DistributedStore store" do
30
50
  store = Redis::Factory.create(
31
51
  {:host => "localhost", :port => 6379},
32
52
  {:host => "localhost", :port => 6380}
33
53
  )
34
- store.should be_kind_of(Redis::DistributedMarshaled)
54
+ store.should be_kind_of(Redis::DistributedStore)
35
55
  store.nodes.map {|node| node.to_s}.should == [
36
56
  "Redis Client connected to localhost:6379 against DB 0",
37
57
  "Redis Client connected to localhost:6380 against DB 0",
@@ -41,26 +61,48 @@ describe "Redis::Factory" do
41
61
 
42
62
  context "when given a String" do
43
63
  it "should allow to specify host" do
44
- store = Redis::Factory.create "localhost"
45
- store.to_s.should == "Redis Client connected to localhost:6379 against DB 0"
64
+ store = Redis::Factory.create "redis://127.0.0.1"
65
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
46
66
  end
47
67
 
48
68
  it "should allow to specify port" do
49
- store = Redis::Factory.create "localhost:6380"
50
- store.to_s.should == "Redis Client connected to localhost:6380 against DB 0"
69
+ store = Redis::Factory.create "redis://127.0.0.1:6380"
70
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6380 against DB 0"
51
71
  end
52
72
 
53
73
  it "should allow to specify db" do
54
- store = Redis::Factory.create "localhost:6380/13"
55
- store.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
74
+ store = Redis::Factory.create "redis://127.0.0.1:6380/13"
75
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6380 against DB 13"
76
+ end
77
+
78
+ it "should allow to specify namespace" do
79
+ store = Redis::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
80
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist"
56
81
  end
57
82
 
58
- it "should instantiate a Redis::DistributedMarshaled store" do
59
- store = Redis::Factory.create "localhost:6379", "localhost:6380"
60
- store.should be_kind_of(Redis::DistributedMarshaled)
83
+ it "should allow to specify scheme" do
84
+ store = Redis::Factory.create "redis://127.0.0.1:6379/0/theplaylist"
85
+ store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0 with namespace theplaylist"
86
+ end
87
+
88
+ it "should allow to specify password" do
89
+ store = Redis::Factory.create "redis://:secret@127.0.0.1:6379/0/theplaylist"
90
+ store.instance_variable_get(:@client).password.should == "secret"
91
+ end
92
+
93
+ it "should allow to specify password without scheme" do
94
+ suppress_warnings do
95
+ store = Redis::Factory.create ":secret@127.0.0.1:6379/0/theplaylist"
96
+ store.instance_variable_get(:@client).password.should == "secret"
97
+ end
98
+ end
99
+
100
+ it "should instantiate a Redis::DistributedStore store" do
101
+ store = Redis::Factory.create "redis://127.0.0.1:6379", "redis://127.0.0.1:6380"
102
+ store.should be_kind_of(Redis::DistributedStore)
61
103
  store.nodes.map {|node| node.to_s}.should == [
62
- "Redis Client connected to localhost:6379 against DB 0",
63
- "Redis Client connected to localhost:6380 against DB 0",
104
+ "Redis Client connected to 127.0.0.1:6379 against DB 0",
105
+ "Redis Client connected to 127.0.0.1:6380 against DB 0",
64
106
  ]
65
107
  end
66
108
  end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ class InterfacedRedis < Redis
4
+ include Redis::Store::Interface
5
+ end
6
+
7
+ describe "Redis::Store::Interface" do
8
+ before :each do
9
+ @r = InterfacedRedis.new
10
+ end
11
+
12
+ it "should get an element" do
13
+ lambda { @r.get("key", :option => true) }.should_not raise_error
14
+ end
15
+
16
+ it "should set an element" do
17
+ lambda { @r.set("key", "value", :option => true) }.should_not raise_error
18
+ end
19
+
20
+ it "should setnx an element" do
21
+ lambda { @r.setnx("key", "value", :option => true) }.should_not raise_error
22
+ end
23
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Redis::Marshalling" do
4
+ before(:each) do
5
+ @store = Redis::Store.new :marshalling => true
6
+ @rabbit = OpenStruct.new :name => "bunny"
7
+ @white_rabbit = OpenStruct.new :color => "white"
8
+ @store.set "rabbit", @rabbit
9
+ @store.del "rabbit2"
10
+ end
11
+
12
+ after :each do
13
+ @store.quit
14
+ end
15
+
16
+ it "should unmarshal an object on get" do
17
+ @store.get("rabbit").should === @rabbit
18
+ end
19
+
20
+ it "should marshal object on set" do
21
+ @store.set "rabbit", @white_rabbit
22
+ @store.get("rabbit").should === @white_rabbit
23
+ end
24
+
25
+ if RUBY_VERSION.match /1\.9/
26
+ it "should not unmarshal object on get if raw option is true" do
27
+ @store.get("rabbit", :raw => true).should == "\x04\bU:\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF"
28
+ end
29
+ else
30
+ it "should not unmarshal object on get if raw option is true" do
31
+ @store.get("rabbit", :raw => true).should == "\004\bU:\017OpenStruct{\006:\tname\"\nbunny"
32
+ end
33
+ end
34
+
35
+ it "should not marshal object on set if raw option is true" do
36
+ @store.set "rabbit", @white_rabbit, :raw => true
37
+ @store.get("rabbit", :raw => true).should == %(#<OpenStruct color="white">)
38
+ end
39
+
40
+ it "should not unmarshal object if getting an empty string" do
41
+ @store.set "empty_string", ""
42
+ lambda { @store.get("empty_string").should == "" }.should_not raise_error
43
+ end
44
+
45
+ it "should not set an object if already exist" do
46
+ @store.setnx "rabbit", @white_rabbit
47
+ @store.get("rabbit").should === @rabbit
48
+ end
49
+
50
+ it "should marshal object on set_unless_exists" do
51
+ @store.setnx "rabbit2", @white_rabbit
52
+ @store.get("rabbit2").should === @white_rabbit
53
+ end
54
+
55
+ it "should not marshal object on set_unless_exists if raw option is true" do
56
+ @store.setnx "rabbit2", @white_rabbit, :raw => true
57
+ @store.get("rabbit2", :raw => true).should == %(#<OpenStruct color="white">)
58
+ end
59
+
60
+ it "should unmarshal object(s) on multi get" do
61
+ @store.set "rabbit2", @white_rabbit
62
+ rabbit, rabbit2 = @store.mget "rabbit", "rabbit2"
63
+ rabbit.should == @rabbit
64
+ rabbit2.should == @white_rabbit
65
+ end
66
+
67
+ if RUBY_VERSION.match /1\.9/
68
+ it "should not unmarshal object(s) on multi get if raw option is true" do
69
+ @store.set "rabbit2", @white_rabbit
70
+ rabbit, rabbit2 = @store.mget "rabbit", "rabbit2", :raw => true
71
+ rabbit.should == "\x04\bU:\x0FOpenStruct{\x06:\tnameI\"\nbunny\x06:\x06EF"
72
+ rabbit2.should == "\x04\bU:\x0FOpenStruct{\x06:\ncolorI\"\nwhite\x06:\x06EF"
73
+ end
74
+ else
75
+ it "should not unmarshal object(s) on multi get if raw option is true" do
76
+ @store.set "rabbit2", @white_rabbit
77
+ rabbit, rabbit2 = @store.mget "rabbit", "rabbit2", :raw => true
78
+ rabbit.should == "\004\bU:\017OpenStruct{\006:\tname\"\nbunny"
79
+ rabbit2.should == "\004\bU:\017OpenStruct{\006:\ncolor\"\nwhite"
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Redis::Store::Namespace" do
4
+ before :each do
5
+ @namespace = "theplaylist"
6
+ @store = Redis::Store.new :namespace => @namespace, :marshalling => false # TODO remove mashalling option
7
+ @client = @store.instance_variable_get(:@client)
8
+ @rabbit = "bunny"
9
+ end
10
+
11
+ after :each do
12
+ @store.should_receive(:quit) # stupid rspec, meh!
13
+ @store.quit
14
+ end
15
+
16
+ it "should only decorate instances that needs to be namespaced" do
17
+ @store = Redis::Store.new
18
+ client = @store.instance_variable_get(:@client)
19
+ client.should_receive(:call).with(:get, "rabbit")
20
+ @store.get("rabbit")
21
+ end
22
+
23
+ it "should not namespace a key which is already namespaced" do
24
+ @store.send(:interpolate, "#{@namespace}:rabbit").should == "#{@namespace}:rabbit"
25
+ end
26
+
27
+ it "should namespace get" do
28
+ @client.should_receive(:call).with(:get, "#{@namespace}:rabbit")
29
+ @store.get("rabbit")
30
+ end
31
+
32
+ it "should namespace set" do
33
+ @client.should_receive(:call).with(:set, "#{@namespace}:rabbit", @rabbit)
34
+ @store.set "rabbit", @rabbit
35
+ end
36
+
37
+ it "should namespace setnx" do
38
+ @client.should_receive(:call).with(:setnx, "#{@namespace}:rabbit", @rabbit)
39
+ @store.setnx "rabbit", @rabbit
40
+ end
41
+
42
+ it "should namespace del with single key" do
43
+ @client.should_receive(:call).with(:del, "#{@namespace}:rabbit")
44
+ @store.del "rabbit"
45
+ end
46
+
47
+ it "should namespace del with multiple keys" do
48
+ @client.should_receive(:call).with(:del, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit")
49
+ @store.del "rabbit", "white_rabbit"
50
+ end
51
+
52
+ it "should namespace keys" do
53
+ @client.should_receive(:call).with(:keys, "#{@namespace}:rabb*").and_return [ "#{@namespace}:rabbit" ]
54
+ @store.keys "rabb*"
55
+ end
56
+
57
+ it "should namespace exists" do
58
+ @client.should_receive(:call).with(:exists, "#{@namespace}:rabbit")
59
+ @store.exists "rabbit"
60
+ end
61
+
62
+ it "should namespace incrby" do
63
+ @client.should_receive(:call).with(:incrby, "#{@namespace}:counter", 1)
64
+ @store.incrby "counter", 1
65
+ end
66
+
67
+ it "should namespace decrby" do
68
+ @client.should_receive(:call).with(:decrby, "#{@namespace}:counter", 1)
69
+ @store.decrby "counter", 1
70
+ end
71
+
72
+ it "should namespace mget" do
73
+ @client.should_receive(:call).with(:mget, "#{@namespace}:rabbit", "#{@namespace}:white_rabbit")
74
+ @store.mget "rabbit", "white_rabbit"
75
+ end
76
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe Redis::Store::VERSION do
4
+ it "should describe Redis::Store version" do
5
+ Redis::Store::VERSION::STRING.should == "1.0.0.beta3"
6
+ end
7
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,13 +3,13 @@ ARGV << "-b"
3
3
  require "rubygems"
4
4
  require "bundler"
5
5
  Bundler.setup
6
-
7
- #require "vendor/gems/environment"
6
+ require "methopara" if RUBY_VERSION.match /1\.9/
8
7
  require "ostruct"
9
8
  require "spec"
10
9
  require "spec/autorun"
11
10
  require "redis"
12
11
  require "merb"
12
+ require "i18n"
13
13
  require "rack/cache"
14
14
  require "rack/cache/metastore"
15
15
  require "rack/cache/entitystore"
@@ -19,10 +19,21 @@ begin
19
19
  require "action_controller/session/abstract_store" # Rails 2.3.x
20
20
  rescue LoadError
21
21
  require "action_dispatch/middleware/session/abstract_store" # Rails 3.x
22
- module Rails; def self.version; "3.0.0.beta4" end end unless defined?(Rails)
22
+ module Rails; def self.version; "3.0.0" end end unless defined?(Rails)
23
23
  end
24
- require "cache/rails/redis_store"
25
- require "rack/session/rails"
24
+ require "active_support/cache/redis_store"
25
+ require "action_controller/session/redis_session_store"
26
26
  require "cache/sinatra/redis_store"
27
27
 
28
28
  $DEBUG = ENV["DEBUG"] === "true"
29
+
30
+ # http://mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/
31
+ module Kernel
32
+ def suppress_warnings
33
+ original_verbosity = $VERBOSE
34
+ $VERBOSE = nil
35
+ result = yield
36
+ $VERBOSE = original_verbosity
37
+ return result
38
+ end
39
+ end