redis-sentinel 1.3.0 → 1.4.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.
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