redis_ring_client 0.0.4 → 0.1.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/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