redis-sentinel 1.3.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 13e25cdba4cbb9a679bc1510df3733769f269084
4
- data.tar.gz: d73c7b49c1056871ec68faa8eb49d6cc6c201eb4
3
+ metadata.gz: 0abad2c1cbcc6e342c7f362b9d6c6ad6ebca6a81
4
+ data.tar.gz: e300689d63cec3fec3f9d2ace82d61d828baf4b3
5
5
  SHA512:
6
- metadata.gz: 733ae6b08e7176b1ae8009ef6c70a7ec0a02ccfecdae4dc5973912e6fd937a73040e297c4155ff2b9248bcd369b93dedba35b58f87934f8bb34ffa63b2d82cae
7
- data.tar.gz: afbcb2c666c307aa7851b1db2b01abfbcf8f1dbabd9f7d9a76805297d450ddbb5657a3ca0723537043bd2c05e6ed5f7ca3c7e8d5f5d3091a1ab6915f25a7c80b
6
+ metadata.gz: 5472ab6c41d452eb5550ed58698871956a57deb51d354c95e154d768b4390871f3f302170ac03987029ad02a5973a471864e4034d2e0195385b9f4f6839d667f
7
+ data.tar.gz: 4c781a86527902cfc4a9fee13b7b0139b39245eadb894f98647e2f3e0a158c5d5128d2218577830b1b1d0d22df963126a7c1f376522952eb1c1501e0f960eb59
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 1.4.0
4
+
5
+ * Rewrite sentinel client to follow http://redis.io/topics/sentinel
6
+ * Parse uri string in sentinels array
7
+
3
8
  ## 1.3.0
4
9
 
5
10
  * Add ability to reconnect all redis sentinel clients
data/README.md CHANGED
@@ -13,6 +13,11 @@ Add this line to your application's Gemfile:
13
13
 
14
14
  gem 'redis-sentinel'
15
15
 
16
+ If you are using redis-server less than 2.6.10, please use
17
+ redis-sentinel 1.3.0
18
+
19
+ gem 'redis-sentinel', '~> 1.3.0'
20
+
16
21
  And then execute:
17
22
 
18
23
  $ bundle
@@ -27,6 +32,11 @@ Specify the sentinel servers and master name
27
32
 
28
33
  Redis.new(master_name: "master1", sentinels: [{host: "localhost", port: 26379}, {host: "localhost", port: 26380}])
29
34
 
35
+ Sentinels can also be specified using a URI. This URI syntax is required when using Rails.config.cache_store:
36
+
37
+ config.cache_store = :redis_store, { master_name: "master1",
38
+ sentinels: ['sentinel://localhost:26379', 'sentinel://localhost:26380'] }
39
+
30
40
  There are two additional options:
31
41
 
32
42
  1. `:failover_reconnect_timeout` (seconds) will block for that long when
@@ -55,6 +65,7 @@ Start 2 sentinel servers
55
65
  ```
56
66
  $ redis-server example/redis-sentinel1.conf --sentinel
57
67
  $ redis-server example/redis-sentinel2.conf --sentinel
68
+ $ redis-server example/redis-sentinel3.conf --sentinel
58
69
  ```
59
70
 
60
71
  Run example/test.rb, which will query value of key "foo" every second.
@@ -84,19 +95,7 @@ takes less than 30 seconds.
84
95
 
85
96
  ## Authors and Contributors
86
97
 
87
- * [Richard Huang](https://github.com/flyerhzm) - Creator of the project
88
- * [Donald Plummer](https://github.com/dplummer) - Add wait / timeout for
89
- redis connection
90
- * [Rafał Michalski](https://github.com/royaltm) - Ensure promoted slave
91
- become master / Add redis synchrony support
92
- * [Zachary Anker](https://github.com/zanker) - Add redis authentication
93
- support
94
- * [Nick Deteffen](https://github.com/nick-desteffen) - Add ability to
95
- reconnect all redis sentinel clients
96
- * [Carlos Paramio](https://github.com/carlosparamio) - Avoid the config
97
- gets modified
98
- * [Michael Gee](https://github.com/mikegee) - Reconnect if redis suddenly
99
- becomes read-only.
98
+ [https://github.com/flyerhzm/redis-sentinel/graphs/contributors](https://github.com/flyerhzm/redis-sentinel/graphs/contributors)
100
99
 
101
100
  Please fork and contribute, any help in making this project better is appreciated!
102
101
 
@@ -2,5 +2,4 @@ port 26379
2
2
  sentinel monitor example-test 127.0.0.1 16379 2
3
3
  sentinel down-after-milliseconds example-test 5000
4
4
  sentinel failover-timeout example-test 900000
5
- sentinel can-failover example-test yes
6
5
  sentinel parallel-syncs example-test 1
@@ -2,5 +2,4 @@ port 26380
2
2
  sentinel monitor example-test 127.0.0.1 16379 2
3
3
  sentinel down-after-milliseconds example-test 5000
4
4
  sentinel failover-timeout example-test 900000
5
- sentinel can-failover example-test yes
6
5
  sentinel parallel-syncs example-test 1
@@ -0,0 +1,5 @@
1
+ port 26381
2
+ sentinel monitor example-test 127.0.0.1 16379 2
3
+ sentinel down-after-milliseconds example-test 5000
4
+ sentinel failover-timeout example-test 900000
5
+ sentinel parallel-syncs example-test 1
@@ -4,11 +4,14 @@ class Redis::Client
4
4
  DEFAULT_FAILOVER_RECONNECT_WAIT_SECONDS = 0.1
5
5
 
6
6
  class_eval do
7
+ attr_reader :current_sentinel
8
+ attr_reader :current_sentinel_options
9
+
7
10
  def initialize_with_sentinel(options={})
8
11
  options = options.dup # Don't touch my options
9
12
  @master_name = fetch_option(options, :master_name)
10
13
  @master_password = fetch_option(options, :master_password)
11
- @sentinels = fetch_option(options, :sentinels)
14
+ @sentinels_options = _parse_sentinel_options(fetch_option(options, :sentinels))
12
15
  @failover_reconnect_timeout = fetch_option(options, :failover_reconnect_timeout)
13
16
  @failover_reconnect_wait = fetch_option(options, :failover_reconnect_wait) ||
14
17
  DEFAULT_FAILOVER_RECONNECT_WAIT_SECONDS
@@ -34,7 +37,7 @@ class Redis::Client
34
37
  alias connect connect_with_sentinel
35
38
 
36
39
  def sentinel?
37
- @master_name && @sentinels
40
+ @master_name && @sentinels_options
38
41
  end
39
42
 
40
43
  def auto_retry_with_timeout(&block)
@@ -49,45 +52,52 @@ class Redis::Client
49
52
  end
50
53
 
51
54
  def try_next_sentinel
52
- @sentinels << @sentinels.shift
53
- if @logger && @logger.debug?
54
- @logger.debug "Trying next sentinel: #{@sentinels[0][:host]}:#{@sentinels[0][:port]}"
55
+ sentinel_options = @sentinels_options.shift
56
+ if sentinel_options
57
+ @logger.debug "Trying next sentinel: #{sentinel_options[:host]}:#{sentinel_options[:port]}" if @logger && @logger.debug?
58
+ @current_sentinel_options = sentinel_options
59
+ @current_sentinel = Redis.new sentinel_options
60
+ else
61
+ raise Redis::CannotConnectError
55
62
  end
56
- return @sentinels[0]
63
+ end
64
+
65
+ def refresh_sentinels_list
66
+ responses = current_sentinel.sentinel("sentinels", @master_name)
67
+ @sentinels_options = responses.map do |response|
68
+ {:host => response[3], :port => response[5]}
69
+ end.unshift(:host => current_sentinel_options[:host], :port => current_sentinel_options[:port])
57
70
  end
58
71
 
59
72
  def discover_master
60
73
  while true
61
- sentinel = redis_sentinels[@sentinels[0]]
74
+ try_next_sentinel
62
75
 
63
76
  begin
64
- host, port = sentinel.sentinel("get-master-addr-by-name", @master_name)
65
- if !host && !port
66
- raise Redis::ConnectionError.new("No master named: #{@master_name}")
77
+ master_host, master_port = current_sentinel.sentinel("get-master-addr-by-name", @master_name)
78
+ if master_host && master_port
79
+ # An ip:port pair
80
+ @options.merge!(:host => master_host, :port => master_port.to_i, :password => @master_password)
81
+ refresh_sentinels_list
82
+ break
83
+ else
84
+ # A null reply
67
85
  end
68
- is_down, runid = sentinel.sentinel("is-master-down-by-addr", host, port)
69
- break
86
+ rescue Redis::CommandError
87
+ # An -IDONTKNOWN reply
70
88
  rescue Redis::CannotConnectError
71
- try_next_sentinel
89
+ # faile to connect to current sentinel server
72
90
  end
73
91
  end
74
-
75
- if is_down.to_s == "1" || runid == '?'
76
- raise Redis::CannotConnectError.new("The master: #{@master_name} is currently not available.")
77
- else
78
- @options.merge!(:host => host, :port => port.to_i, :password => @master_password)
79
- end
80
92
  end
81
93
 
82
- def reconnect_with_sentinels
83
- redis_sentinels.each do |config, sentinel|
84
- sentinel.client.reconnect
85
- end
86
- reconnect_without_sentinels
94
+ def disconnect_with_sentinels
95
+ current_sentinel.client.disconnect if current_sentinel
96
+ disconnect_without_sentinels
87
97
  end
88
98
 
89
- alias reconnect_without_sentinels reconnect
90
- alias reconnect reconnect_with_sentinels
99
+ alias disconnect_without_sentinels disconnect
100
+ alias disconnect disconnect_with_sentinels
91
101
 
92
102
  def call_with_readonly_protection(*args, &block)
93
103
  tries = 0
@@ -110,10 +120,22 @@ class Redis::Client
110
120
  options.delete(key) || options.delete(key.to_s)
111
121
  end
112
122
 
113
- def redis_sentinels
114
- @redis_sentinels ||= Hash.new do |hash, config|
115
- hash[config] = Redis.new(config)
123
+ def _parse_sentinel_options(options)
124
+ return if options.nil?
125
+
126
+ sentinel_options = []
127
+ options.each do |sentinel_option|
128
+ if sentinel_option.is_a?(Hash)
129
+ sentinel_options << sentinel_option
130
+ else
131
+ uri = URI.parse(sentinel_option)
132
+ sentinel_options << {
133
+ host: uri.host,
134
+ port: uri.port
135
+ }
136
+ end
116
137
  end
138
+ sentinel_options
117
139
  end
118
140
  end
119
141
  end
@@ -1,5 +1,5 @@
1
1
  class Redis
2
2
  module Sentinel
3
- VERSION = "1.3.0"
3
+ VERSION = "1.4.0"
4
4
  end
5
5
  end
@@ -4,105 +4,107 @@ describe Redis::Client do
4
4
  let(:client) { double("Client", :reconnect => true) }
5
5
  let(:redis) { double("Redis", :sentinel => ["remote.server", 8888], :client => client) }
6
6
 
7
+ let(:sentinels) do
8
+ [
9
+ { :host => "localhost", :port => 26379 },
10
+ 'sentinel://localhost:26380'
11
+ ]
12
+ end
13
+
7
14
  subject { Redis::Client.new(:master_name => "master", :master_password => "foobar",
8
- :sentinels => [{:host => "localhost", :port => 26379},
9
- {:host => "localhost", :port => 26380}]) }
15
+ :sentinels => sentinels) }
10
16
 
11
- before { Redis.stub(:new).and_return(redis) }
17
+ before do
18
+ allow(Redis).to receive(:new).and_return(redis)
19
+ end
12
20
 
13
21
  context "#sentinel?" do
14
22
  it "should be true if passing sentiels and master_name options" do
15
- expect(Redis::Client.new(:master_name => "master", :sentinels => [{:host => "localhost", :port => 26379}, {:host => "localhost", :port => 26380}])).to be_sentinel
23
+ expect(subject).to be_sentinel
16
24
  end
17
25
 
18
- it "should not be true if not passing sentinels and maser_name options" do
26
+ it "should not be true if not passing sentinels and master_name options" do
19
27
  expect(Redis::Client.new).not_to be_sentinel
20
28
  end
21
29
 
22
30
  it "should not be true if passing sentinels option but not master_name option" do
23
- expect(Redis::Client.new(:sentinels => [{:host => "localhost", :port => 26379}, {:host => "localhost", :port => 26380}])).not_to be_sentinel
31
+ client = Redis::Client.new(
32
+ :sentinels => [
33
+ {:host => "localhost", :port => 26379},
34
+ {:host => "localhost", :port => 26380}
35
+ ])
36
+ expect(client).not_to be_sentinel
24
37
  end
25
38
 
26
39
  it "should not be true if passing master_name option but not sentinels option" do
27
- expect(Redis::Client.new(:master_name => "master")).not_to be_sentinel
40
+ client = Redis::Client.new(:master_name => "master")
41
+ expect(client).not_to be_sentinel
28
42
  end
29
- end
30
43
 
31
- context "#try_next_sentinel" do
32
- it "should return next sentinel server" do
33
- expect(subject.try_next_sentinel).to eq({:host => "localhost", :port => 26380})
44
+ it "should be true if passing master_name, and sentinels as uri" do
45
+ client = Redis::Client.new(:master_name => "master",
46
+ :sentinels => %w(sentinel://localhost:26379 sentinel://localhost:26380))
47
+ expect(client).to be_sentinel
34
48
  end
35
49
  end
36
50
 
37
- context "#discover_master" do
38
- it "gets the current master" do
39
- redis.should_receive(:sentinel).
40
- with("get-master-addr-by-name", "master")
41
- redis.should_receive(:sentinel).
42
- with("is-master-down-by-addr", "remote.server", 8888)
43
- subject.discover_master
51
+ context "#try_next_sentinel" do
52
+ it "returns next sentinel server" do
53
+ expect(Redis).to receive(:new).with(:host => "localhost", :port => 26379).and_return(redis)
54
+ subject.try_next_sentinel
44
55
  end
45
56
 
46
- it "should update options" do
47
- redis.should_receive(:sentinel).
48
- with("is-master-down-by-addr", "remote.server", 8888).once.
49
- and_return([0, "abc"])
50
- subject.discover_master
51
- expect(subject.host).to eq "remote.server"
52
- expect(subject.port).to eq 8888
53
- expect(subject.password).to eq "foobar"
57
+ it "raises an error if no available sentinel server" do
58
+ client = Redis::Client.new(
59
+ :master_name => "master",
60
+ :sentinels => []
61
+ )
62
+ expect { client.try_next_sentinel }.to raise_error(Redis::CannotConnectError)
54
63
  end
64
+ end
55
65
 
56
- it "should not update options" do
57
- redis.should_receive(:sentinel).
58
- with("is-master-down-by-addr", "remote.server", 8888).twice.
59
- and_return([1, "abc"], [0, "?"])
60
- 2.times do
61
- expect do
62
- subject.discover_master
63
- end.to raise_error(Redis::CannotConnectError, /currently not available/)
64
- expect(subject.host).not_to eq "remote.server"
65
- expect(subject.port).not_to eq 8888
66
- expect(subject.password).not_to eq "foobar"
67
- end
66
+ context "#refresh_sentinels_list" do
67
+ it "gets all sentinels list" do
68
+ sentinel = double('sentinel')
69
+ allow(subject).to receive(:current_sentinel_options).and_return(:host => "localhost", :port => 26379)
70
+ expect(subject).to receive(:current_sentinel).and_return(sentinel)
71
+ expect(sentinel).to receive(:sentinel).with("sentinels", "master").and_return([
72
+ ["name", "localhost:26381", "ip", "localhost", "port", 26380],
73
+ ["name", "localhost:26381", "ip", "localhost", "port", 26381]
74
+ ])
75
+ subject.refresh_sentinels_list
76
+ expect(subject.instance_variable_get(:@sentinels_options)).to eq [
77
+ {:host => "localhost", :port => 26379},
78
+ {:host => "localhost", :port => 26380},
79
+ {:host => "localhost", :port => 26381}
80
+ ]
68
81
  end
82
+ end
69
83
 
70
- it "should not use a password" do
71
- Redis.should_receive(:new).with({:host => "localhost", :port => 26379})
72
- redis.should_receive(:sentinel).with("get-master-addr-by-name", "master")
73
- redis.should_receive(:sentinel).with("is-master-down-by-addr", "remote.server", 8888)
74
-
75
- redis = Redis::Client.new(:master_name => "master", :sentinels => [{:host => "localhost", :port => 26379}])
76
- redis.discover_master
77
-
78
- expect(redis.host).to eq "remote.server"
79
- expect(redis.port).to eq 8888
80
- expect(redis.password).to eq nil
84
+ context "#discover_master" do
85
+ it "updates master config options" do
86
+ expect(redis).to receive(:sentinel).with("get-master-addr-by-name", "master").and_return(["master", 8888])
87
+ expect(redis).to receive(:sentinel).with("sentinels", "master").and_return([{:host => "sentinel", :port => 8888}])
88
+ subject.discover_master
89
+ expect(subject.host).to eq "master"
90
+ expect(subject.port).to eq 8888
81
91
  end
82
92
 
83
- it "should select next sentinel" do
84
- Redis.should_receive(:new).with({:host => "localhost", :port => 26379})
85
- redis.should_receive(:sentinel).
86
- with("get-master-addr-by-name", "master").
87
- and_raise(Redis::CannotConnectError)
88
- Redis.should_receive(:new).with({:host => "localhost", :port => 26380})
89
- redis.should_receive(:sentinel).
90
- with("get-master-addr-by-name", "master")
91
- redis.should_receive(:sentinel).
92
- with("is-master-down-by-addr", "remote.server", 8888)
93
+ it "selects next sentinel if failed to connect to current_sentinel" do
94
+ expect(subject).to receive(:current_sentinel).and_return(redis)
95
+ expect(redis).to receive(:sentinel).with("get-master-addr-by-name", "master").and_raise(Redis::CannotConnectError)
96
+ sentinel = double('sentinel')
97
+ expect(subject).to receive(:current_sentinel).and_return(sentinel)
98
+ expect(sentinel).to receive(:sentinel).with("get-master-addr-by-name", "master").and_return(["master", 8888])
99
+ allow(subject).to receive(:refresh_sentinels_list)
93
100
  subject.discover_master
94
- expect(subject.host).to eq "remote.server"
101
+ expect(subject.host).to eq "master"
95
102
  expect(subject.port).to eq 8888
96
- expect(subject.password).to eq "foobar"
97
103
  end
98
104
 
99
- describe "memoizing sentinel connections" do
100
- it "does not reconnect to the sentinels" do
101
- Redis.should_receive(:new).once
102
-
103
- subject.discover_master
104
- subject.discover_master
105
- end
105
+ it "raises error if try_next_sentinel raises error" do
106
+ expect(subject).to receive(:try_next_sentinel).and_raise(Redis::CannotConnectError)
107
+ expect { subject.discover_master }.to raise_error(Redis::CannotConnectError)
106
108
  end
107
109
  end
108
110
 
@@ -111,7 +113,7 @@ describe Redis::Client do
111
113
  subject { Redis::Client.new }
112
114
 
113
115
  it "does not sleep" do
114
- subject.should_not_receive(:sleep)
116
+ expect(subject).not_to receive(:sleep)
115
117
  expect do
116
118
  subject.auto_retry_with_timeout { raise Redis::CannotConnectError }
117
119
  end.to raise_error(Redis::CannotConnectError)
@@ -122,12 +124,12 @@ describe Redis::Client do
122
124
  subject { Redis::Client.new(:failover_reconnect_timeout => 3) }
123
125
 
124
126
  before(:each) do
125
- subject.stub(:sleep)
127
+ allow(subject).to receive(:sleep)
126
128
  end
127
129
 
128
130
  it "only raises after the failover_reconnect_timeout" do
129
131
  called_counter = 0
130
- Time.stub(:now).and_return(100, 101, 102, 103, 104, 105)
132
+ allow(Time).to receive(:now).and_return(100, 101, 102, 103, 104, 105)
131
133
 
132
134
  begin
133
135
  subject.auto_retry_with_timeout do
@@ -137,12 +139,12 @@ describe Redis::Client do
137
139
  rescue Redis::CannotConnectError
138
140
  end
139
141
 
140
- called_counter.should == 4
142
+ expect(called_counter).to eq(4)
141
143
  end
142
144
 
143
145
  it "sleeps the default wait time" do
144
- Time.stub(:now).and_return(100, 101, 105)
145
- subject.should_receive(:sleep).with(0.1)
146
+ allow(Time).to receive(:now).and_return(100, 101, 105)
147
+ expect(subject).to receive(:sleep).with(0.1)
146
148
  begin
147
149
  subject.auto_retry_with_timeout { raise Redis::CannotConnectError }
148
150
  rescue Redis::CannotConnectError
@@ -150,7 +152,7 @@ describe Redis::Client do
150
152
  end
151
153
 
152
154
  it "does not catch other errors" do
153
- subject.should_not_receive(:sleep)
155
+ expect(subject).not_to receive(:sleep)
154
156
  expect do
155
157
  subject.auto_retry_with_timeout { raise Redis::ConnectionError }
156
158
  end.to raise_error(Redis::ConnectionError)
@@ -161,8 +163,8 @@ describe Redis::Client do
161
163
  :failover_reconnect_wait => 0.01) }
162
164
 
163
165
  it "uses the configured wait time" do
164
- Time.stub(:now).and_return(100, 101, 105)
165
- subject.should_receive(:sleep).with(0.01)
166
+ allow(Time).to receive(:now).and_return(100, 101, 105)
167
+ expect(subject).to receive(:sleep).with(0.01)
166
168
  begin
167
169
  subject.auto_retry_with_timeout { raise Redis::CannotConnectError }
168
170
  rescue Redis::CannotConnectError
@@ -172,15 +174,14 @@ describe Redis::Client do
172
174
  end
173
175
  end
174
176
 
175
- context "#reconnect" do
176
- it "calls reconnect on each sentinel client" do
177
- subject.stub(:connect)
178
- subject.discover_master
179
- subject.send(:redis_sentinels).each do |config, sentinel|
180
- sentinel.client.should_receive(:reconnect)
181
- end
182
-
183
- subject.reconnect
177
+ context "#disconnect" do
178
+ it "calls disconnect on each sentinel client" do
179
+ sentinel = double('sentinel')
180
+ client = double('client')
181
+ allow(subject).to receive(:current_sentinel).and_return(sentinel)
182
+ expect(sentinel).to receive(:client).and_return(client)
183
+ expect(client).to receive(:disconnect)
184
+ subject.disconnect
184
185
  end
185
186
  end
186
187
 
@@ -9,24 +9,24 @@ describe Redis::Client do
9
9
  context "configured wait time" do
10
10
 
11
11
  it "uses the wait time and blocks em" do
12
- Time.stub(:now).and_return(100, 101, 105)
12
+ allow(Time).to receive(:now).and_return(100, 101, 105)
13
13
  flag = false; EM.next_tick { flag = true }
14
- subject.should_receive(:sleep).with(0.1).and_return(0.1)
14
+ expect(subject).to receive(:sleep).with(0.1).and_return(0.1)
15
15
  begin
16
16
  subject.auto_retry_with_timeout { raise Redis::CannotConnectError }
17
17
  rescue Redis::CannotConnectError
18
18
  end
19
- flag.should be_false
19
+ expect(flag).to be_false
20
20
  end
21
21
 
22
22
  it "uses the wait time and doesn't block em" do
23
- Time.stub(:now).and_return(100, 101, 105)
23
+ allow(Time).to receive(:now).and_return(100, 101, 105)
24
24
  flag = false; EM.next_tick { flag = true }
25
25
  begin
26
26
  subject.auto_retry_with_timeout { raise Redis::CannotConnectError }
27
27
  rescue Redis::CannotConnectError
28
28
  end
29
- flag.should be_true
29
+ expect(flag).to be_true
30
30
  end
31
31
  end
32
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: redis-sentinel
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Richard Huang
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-08-25 00:00:00.000000000 Z
11
+ date: 2014-01-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis
@@ -114,6 +114,7 @@ files:
114
114
  - example/redis-master.conf
115
115
  - example/redis-sentinel1.conf
116
116
  - example/redis-sentinel2.conf
117
+ - example/redis-sentinel3.conf
117
118
  - example/redis-slave.conf
118
119
  - example/test.rb
119
120
  - example/test_wait_for_failover.rb
@@ -145,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
146
  version: '0'
146
147
  requirements: []
147
148
  rubyforge_project:
148
- rubygems_version: 2.0.6
149
+ rubygems_version: 2.0.14
149
150
  signing_key:
150
151
  specification_version: 4
151
152
  summary: another redis automatic master/slave failover solution for ruby by using