red_cluster 0.0.1 → 0.0.2

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.
@@ -10,20 +10,6 @@ class RedCluster
10
10
  @replica_sets = replica_sets.map { |replica_set| ReplicaSet.new(self, replica_set) }
11
11
  end
12
12
 
13
- def load_aof_file(file_path)
14
- aof_file = File.read file_path
15
- commands = aof_file.split /^\*/
16
- commands.each do |cmd|
17
- split_cmd = cmd.split("\r\n")[1..-1]
18
- next unless split_cmd
19
- split_cmd.reject! { |cmd| cmd =~ /^\$/ }
20
- redis_cmd, redis_key, redis_args = split_cmd[0], split_cmd[1], split_cmd[2..-1]
21
- crc32_of_key = Zlib.crc32(redis_key).abs
22
- replica_set = @replica_sets[crc32_of_key % @replica_sets.size]
23
- replica_set.master.send redis_cmd, redis_key, *redis_args
24
- end
25
- end
26
-
27
13
  SINGLE_KEY_KEY_OPS = %W{del exists expire expireat move persists ttl type}.map(&:to_sym)
28
14
  STRING_OPS = %W{append decr decrby get getbit getrange getset incr incrby mget mset msetnx set setbit setex setnx setrange strlen}.map(&:to_sym)
29
15
  HASH_OPS = %W{hdel hexists hget hgetall hincrby hkeys hlen hmget hmset hset hsetnx hvals}.map(&:to_sym)
@@ -33,15 +19,19 @@ class RedCluster
33
19
  SINGLE_KEY_OPS = SINGLE_KEY_KEY_OPS + STRING_OPS + HASH_OPS + SINGLE_KEY_LIST_OPS + SINGLE_KEY_SET_OPS + SINGLE_KEY_SORTED_SET_OPS
34
20
 
35
21
  # Server Ops
36
- def select(db); @replica_sets.each {|srvr| srvr.select(db) }; "OK"; end
37
- def echo(msg); @replica_sets.each {|srvr| srvr.echo(msg) }; msg; end
38
- def flushdb; @replica_sets.each(&:flushdb); end
39
- def shutdown; @replica_sets.each(&:shutdown); end
40
- def flushall; @replica_sets.each { |rs| rs.flushall }; "OK"; end
41
- def quit; @replica_sets.each(&:quit); "OK"; end
22
+ def select(db); @replica_sets.each {|replica_set| replica_set.select(db) }; "OK"; end
23
+
24
+ [:flushdb, :shutdown, :flushall, :quit, :multi].each do |method|
25
+ define_method method do
26
+ perform_across_all_replica_sets method
27
+ end
28
+ end
29
+
42
30
  def ping; @replica_sets.each(&:ping); "PONG"; end
43
- def keys(pattern); @replica_sets.map { |server| server.keys pattern }.flatten; end
44
31
  def bgsave; @replica_sets.each(&:bgsave); "Background saving started"; end
32
+ def echo(msg); @replica_sets.each {|replica_set| replica_set.echo(msg) }; msg; end
33
+
34
+ def keys(pattern); @replica_sets.map { |replica_set| replica_set.keys pattern }.flatten; end
45
35
  def lastsave; @replica_sets.map(&:lastsave).min; end
46
36
 
47
37
  def config(cmd, *args)
@@ -54,8 +44,6 @@ class RedCluster
54
44
  end
55
45
 
56
46
  # Transaction Ops
57
- def multi; @replica_sets.each(&:multi); end
58
-
59
47
  def exec
60
48
  @multi_count = nil
61
49
  exec_results = @replica_sets.map(&:exec)
@@ -152,7 +140,27 @@ class RedCluster
152
140
  end
153
141
  end
154
142
 
143
+ def load_aof_file(file_path)
144
+ aof_file = File.read file_path
145
+ commands = aof_file.split /^\*/
146
+ commands.each do |cmd|
147
+ split_cmd = cmd.split("\r\n")[1..-1]
148
+ next unless split_cmd
149
+ split_cmd.reject! { |cmd| cmd =~ /^\$/ }
150
+ redis_cmd, redis_key, redis_args = split_cmd[0], split_cmd[1], split_cmd[2..-1]
151
+ crc32_of_key = Zlib.crc32(redis_key).abs
152
+ replica_set = @replica_sets[crc32_of_key % @replica_sets.size]
153
+ replica_set.master.send redis_cmd, redis_key, *redis_args
154
+ end
155
+ end
156
+
155
157
  private
158
+
159
+ def perform_across_all_replica_sets(op, return_msg = 'OK')
160
+ @replica_sets.each { |replica_set| replica_set.send op }
161
+ return_msg
162
+ end
163
+
156
164
  def replica_set_for_key(key)
157
165
  @replica_sets[Zlib.crc32(key).abs % @replica_sets.size]
158
166
  end
@@ -25,26 +25,6 @@ describe RedCluster do
25
25
  let(:rc) { @rc }
26
26
  after { rc.flushall }
27
27
 
28
- it "gets initialized with a bunch of replica sets" do
29
- first_replica_set = {
30
- :master => {:host => "localhost", :port => 6379},
31
- :slaves => [{:host => "localhost", :port => 7379},
32
- {:host => "localhost", :port => 8379}]
33
- }
34
- second_replica_set = {
35
- :master => {:host => "localhost", :port => 9379},
36
- :slaves => [{:host => "localhost", :port => 10379},
37
- {:host => "localhost", :port => 11379}]
38
- }
39
- third_replica_set = {
40
- :master => {:host => "localhost", :port => 12379},
41
- :slaves => [{:host => "localhost", :port => 13379},
42
- {:host => "localhost", :port => 14379}]
43
- }
44
- replica_sets = [first_replica_set, second_replica_set, third_replica_set]
45
- RedCluster.new replica_sets
46
- end
47
-
48
28
  context "#randomkey", :fast => true do
49
29
  it "returns a random key across the cluster", :fast => true do
50
30
  rc.set "foo", "bar"
@@ -250,8 +230,8 @@ describe RedCluster do
250
230
 
251
231
  context "#echo", :fast => true do
252
232
  it "echo's all replica_sets" do
253
- rc.replica_sets.each { |rs| rs.should_receive(:echo).with("hello") }
254
- rc.echo("hello").should == "hello"
233
+ rc.echo('hello').should == 'hello'
234
+ # rc.replica_sets.each { |rs| rs.should_receive(:echo).with("hello") }
255
235
  end
256
236
  end
257
237
 
@@ -2,117 +2,105 @@ require 'spec_helper'
2
2
  require 'replica_set'
3
3
 
4
4
  describe RedCluster::ReplicaSet do
5
- context "#initializtion" do
6
- it "gets initialized with one master & one or more slaves" do
7
- master = {:host => "localhost", :port => 6379}
8
- slaves = [{:host => "localhost", :port => 7379},
9
- {:host => "localhost", :port => 8379}]
10
- RedCluster::ReplicaSet.new nil, :master => master, :slaves => slaves
5
+ before(:each) do
6
+ master = {:host => "localhost", :port => 6379}
7
+ slaves = [{:host => "localhost", :port => 7379},
8
+ {:host => "localhost", :port => 8379}]
9
+ @rs = RedCluster::ReplicaSet.new nil, :master => master, :slaves => slaves
10
+ end
11
+ let(:rs) { @rs }
12
+ let(:master) { @rs.master }
13
+ let(:slaves) { @rs.slaves }
14
+ after { master.flushall }
15
+
16
+ context "#replication" do
17
+ it "the slaves are slaveof's master" do
18
+ slaves.each do |slave|
19
+ slave.info["role"].should == "slave"
20
+ slave.info["master_host"].should == master.client.host
21
+ slave.info["master_port"].should == master.client.port.to_s
22
+ end
11
23
  end
12
24
  end
13
25
 
14
- context "#other characteristics" do
26
+ context "master dying" do
15
27
  before(:each) do
16
- master = {:host => "localhost", :port => 6379}
17
- slaves = [{:host => "localhost", :port => 7379},
18
- {:host => "localhost", :port => 8379}]
19
- @rs = RedCluster::ReplicaSet.new nil, :master => master, :slaves => slaves
28
+ master.stubs(:set).raises Errno::ECONNREFUSED
20
29
  end
21
- let(:rs) { @rs }
22
- let(:master) { @rs.master }
23
- let(:slaves) { @rs.slaves }
24
- after { master.flushall }
25
-
26
- context "#replication" do
27
- it "the slaves are slaveof's master" do
28
- slaves.each do |slave|
29
- slave.info["role"].should == "slave"
30
- slave.info["master_host"].should == master.client.host
31
- slave.info["master_port"].should == master.client.port.to_s
32
- end
30
+ context "when it's a read op" do
31
+ it "things work as though nothing happened" do
32
+ expect { rs.get("foo") }.to_not raise_error
33
33
  end
34
34
  end
35
35
 
36
- context "master dying" do
37
- before(:each) do
38
- master.stubs(:set).raises Errno::ECONNREFUSED
39
- end
40
- context "when it's a read op" do
41
- it "things work as though nothing happened" do
42
- expect { rs.get("foo") }.to_not raise_error
43
- end
36
+ context "when there are more than one slave" do
37
+ it "one of them gets promoted to the new master" do
38
+ old_slaves = slaves.dup
39
+ old_master = master
40
+ rs.set("foo", "bar")
41
+ old_master.should_not == rs.master
42
+ old_slaves.should include(rs.master)
44
43
  end
45
-
46
- context "when there are more than one slave" do
47
- it "one of them gets promoted to the new master" do
48
- old_slaves = slaves.dup
49
- old_master = master
50
- rs.set("foo", "bar")
51
- old_master.should_not == rs.master
52
- old_slaves.should include(rs.master)
53
- end
54
- it "the other's become slaves of the new master" do
55
- rs.set("foo", "bar")
56
- new_master = rs.master
57
- rs.slaves.each do |slave|
58
- slave.info["master_host"].should == new_master.client.host
59
- slave.info["master_port"].should == new_master.client.port.to_s
60
- end
44
+ it "the other's become slaves of the new master" do
45
+ rs.set("foo", "bar")
46
+ new_master = rs.master
47
+ rs.slaves.each do |slave|
48
+ slave.info["master_host"].should == new_master.client.host
49
+ slave.info["master_port"].should == new_master.client.port.to_s
61
50
  end
62
51
  end
63
- context "when there is just one slave" do
64
- it "becomes the new master" do
65
- slaves.shift while slaves.count > 1
66
- slaves.count.should == 1
67
- old_slave = slaves[0]
68
- rs.set('foo', 'bar')
69
- old_slave.should == rs.master
70
- end
52
+ end
53
+ context "when there is just one slave" do
54
+ it "becomes the new master" do
55
+ slaves.shift while slaves.count > 1
56
+ slaves.count.should == 1
57
+ old_slave = slaves[0]
58
+ rs.set('foo', 'bar')
59
+ old_slave.should == rs.master
71
60
  end
72
- context "when there are no slaves" do
73
- it "a RedCluster::NoMaster exception get's thrown" do
74
- slaves.shift while slaves.count > 0
75
- expect { rs.set('foo', 'bar') }.to raise_error(RedCluster::NoMaster, "No master in replica set")
76
- end
61
+ end
62
+ context "when there are no slaves" do
63
+ it "a RedCluster::NoMaster exception get's thrown" do
64
+ slaves.shift while slaves.count > 0
65
+ expect { rs.set('foo', 'bar') }.to raise_error(RedCluster::NoMaster, "No master in replica set")
77
66
  end
78
67
  end
68
+ end
79
69
 
80
- context "#read operations" do
81
- it "get forwarded to the slaves on a round-robin basis" do
82
- master.expects(:get).never
83
- slaves[0].expects(:get).with("some_key").returns "some_val"
84
- slaves[1].expects(:get).with("some_key").returns "some_new_val"
70
+ context "#read operations" do
71
+ it "get forwarded to the slaves on a round-robin basis" do
72
+ master.expects(:get).never
73
+ slaves[0].expects(:get).with("some_key").returns "some_val"
74
+ slaves[1].expects(:get).with("some_key").returns "some_new_val"
85
75
 
86
- rs.get("some_key").should == "some_val"
87
- rs.get("some_key").should == "some_new_val"
88
- end
76
+ rs.get("some_key").should == "some_val"
77
+ rs.get("some_key").should == "some_new_val"
89
78
  end
79
+ end
90
80
 
91
- context "#write operations" do
92
- it "get forwarded to the master" do
93
- master.expects(:set)
94
- rs.set("foo", "bar")
95
- end
81
+ context "#write operations" do
82
+ it "get forwarded to the master" do
83
+ master.expects(:set)
84
+ rs.set("foo", "bar")
96
85
  end
86
+ end
97
87
 
98
- context "#blocking operations" do
99
- it "raise an error" do
100
- expect { rs.blpop("some_list", 0) }.to raise_error
101
- end
88
+ context "#blocking operations" do
89
+ it "raise an error" do
90
+ expect { rs.blpop("some_list", 0) }.to raise_error
102
91
  end
92
+ end
103
93
 
104
- context "#slaveof operations" do
105
- it "raise an error" do
106
- expect { rs.slaveof("localhost", 6379) }.to raise_error
107
- end
94
+ context "#slaveof operations" do
95
+ it "raise an error" do
96
+ expect { rs.slaveof("localhost", 6379) }.to raise_error
108
97
  end
98
+ end
109
99
 
110
- context "#pub sub operations" do
111
- it "raise an error" do
112
- expect { rs.blpop("publish", 0) }.to raise_error
113
- end
100
+ context "#pub sub operations" do
101
+ it "raise an error" do
102
+ expect { rs.blpop("publish", 0) }.to raise_error
114
103
  end
115
-
116
104
  end
117
105
  end
118
106
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: red_cluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2011-10-25 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: redis
16
- requirement: &70203057663840 !ruby/object:Gem::Requirement
16
+ requirement: &70306677369620 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70203057663840
24
+ version_requirements: *70306677369620
25
25
  description: ! " Red Cluster brings together a set of redis servers and allows
26
26
  you to read and write to them\n as though you were writing to just one. A few
27
27
  of the reasons you might want to consider\n clustering could be:\n\n * Robustness