nono-redis-store 1.0.0
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.
- data/.gitignore +11 -0
- data/CHANGELOG +262 -0
- data/Gemfile +33 -0
- data/Gemfile.lock +194 -0
- data/MIT-LICENSE +20 -0
- data/README.md +191 -0
- data/Rakefile +60 -0
- data/VERSION +1 -0
- data/lib/action_controller/session/redis_session_store.rb +74 -0
- data/lib/active_support/cache/redis_store.rb +228 -0
- data/lib/cache/merb/redis_store.rb +75 -0
- data/lib/cache/sinatra/redis_store.rb +126 -0
- data/lib/i18n/backend/redis.rb +67 -0
- data/lib/rack/cache/redis_entitystore.rb +51 -0
- data/lib/rack/cache/redis_metastore.rb +42 -0
- data/lib/rack/session/merb.rb +32 -0
- data/lib/rack/session/redis.rb +81 -0
- data/lib/redis-store.rb +44 -0
- data/lib/redis/distributed_store.rb +35 -0
- data/lib/redis/factory.rb +46 -0
- 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 +11 -0
- data/redis-store.gemspec +103 -0
- data/spec/action_controller/session/redis_session_store_spec.rb +121 -0
- data/spec/active_support/cache/redis_store_spec.rb +405 -0
- data/spec/cache/merb/redis_store_spec.rb +143 -0
- data/spec/cache/sinatra/redis_store_spec.rb +192 -0
- data/spec/config/master.conf +312 -0
- data/spec/config/single.conf +312 -0
- data/spec/config/slave.conf +312 -0
- data/spec/i18n/backend/redis_spec.rb +56 -0
- data/spec/rack/cache/entitystore/pony.jpg +0 -0
- data/spec/rack/cache/entitystore/redis_spec.rb +120 -0
- data/spec/rack/cache/metastore/redis_spec.rb +255 -0
- data/spec/rack/session/redis_spec.rb +234 -0
- data/spec/redis/distributed_store_spec.rb +47 -0
- data/spec/redis/factory_spec.rb +110 -0
- 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 +43 -0
- data/tasks/redis.tasks.rb +220 -0
- metadata +141 -0
@@ -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
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Redis::Factory" do
|
4
|
+
describe ".create" do
|
5
|
+
context "when not given any arguments" do
|
6
|
+
it "should instantiate a Redis::Store store" do
|
7
|
+
store = Redis::Factory.create
|
8
|
+
store.should be_kind_of(Redis::Store)
|
9
|
+
store.to_s.should == "Redis Client connected to 127.0.0.1:6379 against DB 0"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when given a Hash" do
|
14
|
+
it "should allow to specify host" do
|
15
|
+
store = Redis::Factory.create :host => "localhost"
|
16
|
+
store.to_s.should == "Redis Client connected to localhost:6379 against DB 0"
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should allow to specify port" do
|
20
|
+
store = Redis::Factory.create :host => "localhost", :port => 6380
|
21
|
+
store.to_s.should == "Redis Client connected to localhost:6380 against DB 0"
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should allow to specify db" do
|
25
|
+
store = Redis::Factory.create :host => "localhost", :port => 6380, :db => 13
|
26
|
+
store.to_s.should == "Redis Client connected to localhost:6380 against DB 13"
|
27
|
+
end
|
28
|
+
|
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
|
50
|
+
store = Redis::Factory.create(
|
51
|
+
{:host => "localhost", :port => 6379},
|
52
|
+
{:host => "localhost", :port => 6380}
|
53
|
+
)
|
54
|
+
store.should be_kind_of(Redis::DistributedStore)
|
55
|
+
store.nodes.map {|node| node.to_s}.should == [
|
56
|
+
"Redis Client connected to localhost:6379 against DB 0",
|
57
|
+
"Redis Client connected to localhost:6380 against DB 0",
|
58
|
+
]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "when given a String" do
|
63
|
+
it "should allow to specify host" do
|
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"
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should allow to specify port" do
|
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"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should allow to specify db" do
|
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"
|
81
|
+
end
|
82
|
+
|
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)
|
103
|
+
store.nodes.map {|node| node.to_s}.should == [
|
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",
|
106
|
+
]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
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
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), "/../lib")))
|
2
|
+
ARGV << "-b"
|
3
|
+
require "rubygems"
|
4
|
+
require "bundler"
|
5
|
+
Bundler.setup
|
6
|
+
require "methopara" if RUBY_VERSION.match /1\.9/
|
7
|
+
require "ostruct"
|
8
|
+
require "spec"
|
9
|
+
require "spec/autorun"
|
10
|
+
require "redis"
|
11
|
+
require "merb"
|
12
|
+
require "i18n"
|
13
|
+
require "rack/cache"
|
14
|
+
require "rack/cache/metastore"
|
15
|
+
require "rack/cache/entitystore"
|
16
|
+
require "active_support"
|
17
|
+
begin
|
18
|
+
require "action_controller/session/abstract_store" # Rails 2.3.x
|
19
|
+
rescue LoadError
|
20
|
+
require "action_dispatch/middleware/session/abstract_store" # Rails 3.x
|
21
|
+
module Rails
|
22
|
+
module VERSION
|
23
|
+
MAJOR = 3
|
24
|
+
end
|
25
|
+
end unless defined?(Rails)
|
26
|
+
end
|
27
|
+
require "redis-store"
|
28
|
+
require "active_support/cache/redis_store"
|
29
|
+
require "action_controller/session/redis_session_store"
|
30
|
+
require "cache/sinatra/redis_store"
|
31
|
+
|
32
|
+
$DEBUG = ENV["DEBUG"] === "true"
|
33
|
+
|
34
|
+
# http://mentalized.net/journal/2010/04/02/suppress_warnings_from_ruby/
|
35
|
+
module Kernel
|
36
|
+
def suppress_warnings
|
37
|
+
original_verbosity = $VERBOSE
|
38
|
+
$VERBOSE = nil
|
39
|
+
result = yield
|
40
|
+
$VERBOSE = original_verbosity
|
41
|
+
return result
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,220 @@
|
|
1
|
+
# inspired by old Rake tasks from redis-rb
|
2
|
+
require 'rake'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
class RedisRunner
|
7
|
+
def self.port
|
8
|
+
6379
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.redisdir
|
12
|
+
@@redisdir ||= File.expand_path File.join(File.dirname(__FILE__), '..', 'vendor', 'redis')
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.redisconfdir
|
16
|
+
'/etc/redis.conf'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.dtach_socket
|
20
|
+
'/tmp/redis.dtach'
|
21
|
+
end
|
22
|
+
|
23
|
+
# Just check for existance of dtach socket
|
24
|
+
def self.running?
|
25
|
+
File.exists? dtach_socket
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.start
|
29
|
+
puts 'Detach with Ctrl+\ Re-attach with rake redis:attach'
|
30
|
+
sleep 3
|
31
|
+
exec "dtach -A #{dtach_socket} redis-server #{redisconfdir}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.start_detached
|
35
|
+
system "dtach -n #{dtach_socket} redis-server #{redisconfdir}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.attach
|
39
|
+
exec "dtach -a #{dtach_socket}"
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.stop
|
43
|
+
system %(echo "SHUTDOWN" | nc localhost #{port})
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class SingleRedisRunner < RedisRunner
|
48
|
+
def self.redisconfdir
|
49
|
+
File.expand_path(File.dirname(__FILE__) + "/../spec/config/single.conf")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class MasterRedisRunner < RedisRunner
|
54
|
+
def self.redisconfdir
|
55
|
+
File.expand_path(File.dirname(__FILE__) + "/../spec/config/master.conf")
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.dtach_socket
|
59
|
+
"/tmp/redis_master.dtach"
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.port
|
63
|
+
6380
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class SlaveRedisRunner < RedisRunner
|
68
|
+
def self.redisconfdir
|
69
|
+
File.expand_path(File.dirname(__FILE__) + "/../spec/config/slave.conf")
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.dtach_socket
|
73
|
+
"/tmp/redis_slave.dtach"
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.port
|
77
|
+
6381
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class RedisClusterRunner
|
82
|
+
def self.runners
|
83
|
+
[ SingleRedisRunner, MasterRedisRunner, SlaveRedisRunner ]
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.start_detached
|
87
|
+
runners.each do |runner|
|
88
|
+
runner.start_detached
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.stop
|
93
|
+
runners.each do |runner|
|
94
|
+
runner.stop
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
namespace :redis do
|
100
|
+
desc 'About redis'
|
101
|
+
task :about do
|
102
|
+
puts "\nSee http://code.google.com/p/redis/ for information about redis.\n\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
desc 'Start redis'
|
106
|
+
task :start do
|
107
|
+
RedisRunner.start
|
108
|
+
end
|
109
|
+
|
110
|
+
desc 'Stop redis'
|
111
|
+
task :stop do
|
112
|
+
RedisRunner.stop
|
113
|
+
end
|
114
|
+
|
115
|
+
desc 'Restart redis'
|
116
|
+
task :restart do
|
117
|
+
RedisRunner.stop
|
118
|
+
RedisRunner.start
|
119
|
+
end
|
120
|
+
|
121
|
+
desc 'Attach to redis dtach socket'
|
122
|
+
task :attach do
|
123
|
+
RedisRunner.attach
|
124
|
+
end
|
125
|
+
|
126
|
+
desc 'Install the lastest verison of Redis from Github (requires git, duh)'
|
127
|
+
task :install => [ :about, :download, :make ] do
|
128
|
+
%w(redis-benchmark redis-cli redis-server).each do |bin|
|
129
|
+
if File.exist?(path = "#{RedisRunner.redisdir}/src/#{bin}")
|
130
|
+
sh "sudo cp #{path} /usr/bin/"
|
131
|
+
else
|
132
|
+
sh "sudo cp #{RedisRunner.redisdir}/#{bin} /usr/bin/"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
puts "Installed redis-benchmark, redis-cli and redis-server to /usr/bin/"
|
137
|
+
|
138
|
+
sh "sudo cp #{RedisRunner.redisdir}/redis.conf /etc/"
|
139
|
+
puts "Installed redis.conf to /etc/ \n You should look at this file!"
|
140
|
+
end
|
141
|
+
|
142
|
+
task :make do
|
143
|
+
sh "cd #{RedisRunner.redisdir} && make clean"
|
144
|
+
sh "cd #{RedisRunner.redisdir} && make"
|
145
|
+
end
|
146
|
+
|
147
|
+
desc "Download package"
|
148
|
+
task :download do
|
149
|
+
require 'git'
|
150
|
+
|
151
|
+
sh "rm -rf #{RedisRunner.redisdir} && mkdir -p vendor && rm -rf redis"
|
152
|
+
Git.clone("git://github.com/antirez/redis.git", "redis")
|
153
|
+
sh "mv redis vendor"
|
154
|
+
|
155
|
+
commit = case ENV['VERSION']
|
156
|
+
when "1.2.6" then "570e43c8285a4e5e3f31"
|
157
|
+
end
|
158
|
+
|
159
|
+
arguments = commit.nil? ? "pull origin master" : "reset --hard #{commit}"
|
160
|
+
sh "cd #{RedisRunner.redisdir} && git #{arguments}"
|
161
|
+
end
|
162
|
+
|
163
|
+
desc "Open an IRb session"
|
164
|
+
task :console do
|
165
|
+
RedisRunner.start_detached
|
166
|
+
system "bundle exec irb -I lib -I extra -r redis-store.rb"
|
167
|
+
RedisRunner.stop
|
168
|
+
end
|
169
|
+
|
170
|
+
namespace :cluster do
|
171
|
+
desc "Starts the redis_cluster"
|
172
|
+
task :start do
|
173
|
+
result = RedisClusterRunner.start_detached
|
174
|
+
raise("Could not start redis-server, aborting.") unless result
|
175
|
+
end
|
176
|
+
|
177
|
+
desc "Stops the redis_cluster"
|
178
|
+
task :stop do
|
179
|
+
RedisClusterRunner.stop
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
namespace :dtach do
|
185
|
+
desc 'About dtach'
|
186
|
+
task :about do
|
187
|
+
puts "\nSee http://dtach.sourceforge.net/ for information about dtach.\n\n"
|
188
|
+
end
|
189
|
+
|
190
|
+
desc 'Install dtach 0.8 from source'
|
191
|
+
task :install => [:about] do
|
192
|
+
|
193
|
+
Dir.chdir('/tmp/')
|
194
|
+
unless File.exists?('/tmp/dtach-0.8.tar.gz')
|
195
|
+
require 'net/http'
|
196
|
+
|
197
|
+
url = 'http://downloads.sourceforge.net/project/dtach/dtach/0.8/dtach-0.8.tar.gz'
|
198
|
+
open('/tmp/dtach-0.8.tar.gz', 'wb') do |file| file.write(open(url).read) end
|
199
|
+
end
|
200
|
+
|
201
|
+
unless File.directory?('/tmp/dtach-0.8')
|
202
|
+
system('tar xzf dtach-0.8.tar.gz')
|
203
|
+
end
|
204
|
+
|
205
|
+
Dir.chdir('/tmp/dtach-0.8/')
|
206
|
+
sh 'cd /tmp/dtach-0.8/ && ./configure && make'
|
207
|
+
sh 'sudo cp /tmp/dtach-0.8/dtach /usr/bin/'
|
208
|
+
|
209
|
+
puts 'Dtach successfully installed to /usr/bin.'
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def invoke_with_redis_cluster(task_name)
|
214
|
+
begin
|
215
|
+
Rake::Task["redis:cluster:start"].invoke
|
216
|
+
Rake::Task[task_name].invoke
|
217
|
+
ensure
|
218
|
+
Rake::Task["redis:cluster:stop"].invoke
|
219
|
+
end
|
220
|
+
end
|