redis_ring_client 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- redis_ring_client (0.0.3)
4
+ redis_ring_client (0.0.4)
5
5
  json
6
6
  redis
7
+ zookeeper
7
8
 
8
9
  GEM
9
10
  remote: http://rubygems.org/
@@ -21,6 +22,7 @@ GEM
21
22
  diff-lcs (~> 1.1.2)
22
23
  rspec-mocks (2.5.0)
23
24
  ruby-prof (0.9.2)
25
+ zookeeper (0.4.3)
24
26
 
25
27
  PLATFORMS
26
28
  ruby
@@ -5,22 +5,18 @@ module RedisRing
5
5
 
6
6
  class RingMetaData
7
7
 
8
- attr_reader :host, :port
8
+ attr_reader :zookeeper_addr, :zookeeper
9
9
 
10
- def initialize(host, port)
11
- @host = host
12
- @port = port
13
- @loaded = false
10
+ def initialize(zookeeper_addr)
11
+ @zookeeper_addr = zookeeper_addr
14
12
  end
15
13
 
16
14
  def reload!
17
15
  json = get_shards_json_string
18
16
  hash = JSON.parse(json)
19
17
 
20
- @ring_size = hash['count']
18
+ @ring_size = hash['ring_size']
21
19
  @shards = (0...@ring_size).map{|n| ShardMetaData.from_json(hash['shards'][n.to_s])}
22
-
23
- @loaded = true
24
20
  end
25
21
 
26
22
  def ring_size
@@ -42,11 +38,19 @@ module RedisRing
42
38
  protected
43
39
 
44
40
  def should_reload?
45
- !@loaded
41
+ !@zookeeper || @watcher.completed?
46
42
  end
47
43
 
48
- def get_shards_json_string
49
- Net::HTTP.get(host, '/shards', port)
44
+ def get_shards_json_string(retries = 0)
45
+ @zookeeper ||= Zookeeper.new(zookeeper_addr)
46
+ @watcher = Zookeeper::WatcherCallback.new
47
+ resp = @zookeeper.get(:path => "/cluster_status", :watcher => @watcher, :watcher_context => "/cluster_status")
48
+ return resp[:data]
49
+ rescue ZookeeperExceptions::ZookeeperException::ConnectionClosed
50
+ raise if retries == 4
51
+ puts "reopening"
52
+ @zookeeper.reopen
53
+ return get_shards_json_string(retries + 1)
50
54
  end
51
55
 
52
56
  end
@@ -59,12 +63,17 @@ module RedisRing
59
63
  @host = host
60
64
  @port = port
61
65
  @status = status
66
+ @sym = :"Redis<#{host}:#{port}>"
62
67
  end
63
68
 
64
69
  def self.from_json(hash)
65
70
  new(hash['host'], hash['port'].to_i, hash['status'].to_sym)
66
71
  end
67
72
 
73
+ def to_sym
74
+ @sym
75
+ end
76
+
68
77
  end
69
78
 
70
79
  end
@@ -151,8 +151,7 @@ module RedisRing
151
151
  end
152
152
 
153
153
  def initialize(opts = {})
154
- @host = opts[:host] || 'localhost'
155
- @port = opts[:port] || 6400
154
+ @zookeeper = opts[:zookeeper] || 'localhost:2181'
156
155
  @db = opts[:db] || 0
157
156
  @password = opts[:password]
158
157
  end
@@ -175,7 +174,7 @@ module RedisRing
175
174
  protected
176
175
 
177
176
  def ring_meta_data
178
- @ring_meta_data ||= RingMetaData.new(@host, @port)
177
+ @ring_meta_data ||= RingMetaData.new(@zookeeper)
179
178
  end
180
179
 
181
180
  def sharder
@@ -13,16 +13,18 @@ module RedisRing
13
13
  end
14
14
 
15
15
  def connection(shard_number)
16
- @connections[shard_number] ||= new_connection_to_shard(shard_number)
16
+ connection, conn_id = @connections[shard_number]
17
+ shard_metadata = metadata.shard(shard_number)
18
+ unless conn_id == shard_metadata.to_sym
19
+ connection = new_connection(shard_metadata.host, shard_metadata.port, db, password)
20
+ conn_id = shard_metadata.to_sym
21
+ @connections[shard_number] = [connection, conn_id]
22
+ end
23
+ connection
17
24
  end
18
25
 
19
26
  protected
20
27
 
21
- def new_connection_to_shard(shard_number)
22
- shard_metadata = metadata.shard(shard_number)
23
- new_connection(shard_metadata.host, shard_metadata.port, db, password)
24
- end
25
-
26
28
  def new_connection(host, port, db, password)
27
29
  Redis.new(:host => host, :port => port, :db => db, :password => password)
28
30
  end
@@ -1,5 +1,5 @@
1
1
  module RedisRing
2
2
  module Client
3
- VERSION = "0.0.4"
3
+ VERSION = "0.1.0"
4
4
  end
5
5
  end
@@ -1,8 +1,8 @@
1
1
  require 'zlib'
2
- require 'net/http'
3
2
 
4
3
  require 'redis'
5
4
  require 'json'
5
+ require 'zookeeper'
6
6
 
7
7
  require 'redis_ring/client/operation_definitions'
8
8
  require 'redis_ring/client/ring_proxy'
@@ -16,6 +16,7 @@ Gem::Specification.new do |s|
16
16
 
17
17
  s.add_dependency 'redis'
18
18
  s.add_dependency 'json'
19
+ s.add_dependency 'zookeeper'
19
20
 
20
21
  s.add_development_dependency 'rspec'
21
22
  s.add_development_dependency 'mocha'
@@ -4,7 +4,7 @@ describe RedisRing::Client::RingMetaData do
4
4
 
5
5
  def sample_shards_hash
6
6
  {
7
- :count => 10,
7
+ :ring_size => 10,
8
8
  :shards => {
9
9
  0 => {:host => '192.168.1.1', :port => 6401, :status => :running},
10
10
  1 => {:host => '192.168.1.1', :port => 6402, :status => :running},
@@ -24,19 +24,23 @@ describe RedisRing::Client::RingMetaData do
24
24
  sample_shards_hash.to_json
25
25
  end
26
26
 
27
+ def stub_zookeeper
28
+ Zookeeper.any_instance.expects(:get).returns(:data => sample_shard_json)
29
+ end
30
+
27
31
  it "should download json lazily" do
28
- @metadata = RedisRing::Client::RingMetaData.new('host', 666)
32
+ @metadata = RedisRing::Client::RingMetaData.new('localhost:2181')
29
33
 
30
- Net::HTTP.expects(:get).with('host', '/shards', 666).returns(sample_shard_json)
34
+ stub_zookeeper
31
35
 
32
36
  @metadata.ring_size.should == 10
33
37
  end
34
38
 
35
39
  context "with sample shards json" do
36
40
  before(:each) do
37
- Net::HTTP.stubs(:get => sample_shard_json)
41
+ stub_zookeeper
38
42
 
39
- @metadata = RedisRing::Client::RingMetaData.new('host', 666)
43
+ @metadata = RedisRing::Client::RingMetaData.new('localhost:2181')
40
44
  end
41
45
 
42
46
  it "should have ring_size of 10" do
@@ -36,8 +36,11 @@ describe RedisRing::Client::RingProxy do
36
36
  end
37
37
 
38
38
  context "with real RedisRing" do
39
- before(:each) do
39
+ before(:all) do
40
40
  @proxy = RedisRing::Client::RingProxy.new
41
+ end
42
+
43
+ before(:each) do
41
44
  @proxy.flushdb
42
45
  end
43
46
 
@@ -24,4 +24,14 @@ describe RedisRing::Client::ShardConnectionPool do
24
24
  @connection_pool.connection(1).should == :foo
25
25
  end
26
26
 
27
+ it "should create a new connection if the metadata changes" do
28
+ @connection_pool.expects(:new_connection).with("host1", 667, @db, @password).returns(:foo).once
29
+ @connection_pool.connection(1).should == :foo
30
+
31
+ @metadata.shards[1] = RedisRing::Client::ShardMetaData.new("host1", 777, :running)
32
+
33
+ @connection_pool.expects(:new_connection).with("host1", 777, @db, @password).returns(:bar).once
34
+ @connection_pool.connection(1).should == :bar
35
+ end
36
+
27
37
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 4
9
- version: 0.0.4
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Adam Pohorecki
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-03-16 00:00:00 +01:00
17
+ date: 2011-03-21 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -44,7 +44,7 @@ dependencies:
44
44
  type: :runtime
45
45
  version_requirements: *id002
46
46
  - !ruby/object:Gem::Dependency
47
- name: rspec
47
+ name: zookeeper
48
48
  prerelease: false
49
49
  requirement: &id003 !ruby/object:Gem::Requirement
50
50
  none: false
@@ -54,10 +54,10 @@ dependencies:
54
54
  segments:
55
55
  - 0
56
56
  version: "0"
57
- type: :development
57
+ type: :runtime
58
58
  version_requirements: *id003
59
59
  - !ruby/object:Gem::Dependency
60
- name: mocha
60
+ name: rspec
61
61
  prerelease: false
62
62
  requirement: &id004 !ruby/object:Gem::Requirement
63
63
  none: false
@@ -70,7 +70,7 @@ dependencies:
70
70
  type: :development
71
71
  version_requirements: *id004
72
72
  - !ruby/object:Gem::Dependency
73
- name: ruby-prof
73
+ name: mocha
74
74
  prerelease: false
75
75
  requirement: &id005 !ruby/object:Gem::Requirement
76
76
  none: false
@@ -82,6 +82,19 @@ dependencies:
82
82
  version: "0"
83
83
  type: :development
84
84
  version_requirements: *id005
85
+ - !ruby/object:Gem::Dependency
86
+ name: ruby-prof
87
+ prerelease: false
88
+ requirement: &id006 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :development
97
+ version_requirements: *id006
85
98
  description: The client counterpart to the RedisRing gem.
86
99
  email:
87
100
  - adam@pohorecki.pl