redis-sentinel 1.4.4 → 1.5.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 +4 -4
- data/CHANGELOG.md +8 -0
- data/README.md +5 -0
- data/Rakefile +1 -1
- data/example/redis-master.conf +1 -1
- data/example/redis-slave.conf +1 -1
- data/lib/redis-sentinel/client.rb +37 -5
- data/lib/redis-sentinel/version.rb +1 -1
- data/spec/redis-sentinel/client_spec.rb +1 -1
- data/spec/redis-sentinel/em_client_spec.rb +2 -1
- metadata +18 -20
- data/.ruby-gemset +0 -1
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 822e055ecb4e148a1bf08b701e21f6712c519373
|
4
|
+
data.tar.gz: de6b225b065c14d3e429f19a94aa786aa728c9f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0b6a20ab1e214763b79a47aa0122ea054e45ee9527512a1a56ffc27f6caea384c495d153fe229cb184459e8482805eef7d3377387a83ed377c0d0710952ecda2
|
7
|
+
data.tar.gz: 00e40455360c4969dca6f38cfe2aa9707ead89f04e4a0eff35565ac3977c471979acc23f22ff18524337867d942734ab37dc3c0a44a3fff3b3012c017f8350f7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,13 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## 1.5.0
|
4
|
+
|
5
|
+
* Subscribe +switch-master again
|
6
|
+
* Prevents master discovery to get stuck in endless loop if sentinels
|
7
|
+
are not available
|
8
|
+
* Always reconnect at least once, even if reconnect timeout is 0
|
9
|
+
* Catch networking errors which bubble up past redis
|
10
|
+
|
3
11
|
## 1.4.4
|
4
12
|
|
5
13
|
* Allow client to return list of slaves
|
data/README.md
CHANGED
@@ -37,6 +37,11 @@ Sentinels can also be specified using a URI. This URI syntax is required when us
|
|
37
37
|
config.cache_store = :redis_store, { master_name: "master1",
|
38
38
|
sentinels: ['sentinel://localhost:26379', 'sentinel://localhost:26380'] }
|
39
39
|
|
40
|
+
After doing the above, you might still see `#<Redis client v3.1.0 for redis://localhost:6379/0>`.
|
41
|
+
This is fine because redis-sentinel will only try to connect when it is actually required.
|
42
|
+
|
43
|
+
However, if none of the sentinel servers can be reached, a Redis::CannotConnectError will be thrown.
|
44
|
+
|
40
45
|
There are two additional options:
|
41
46
|
|
42
47
|
1. `:failover_reconnect_timeout` (seconds) will block for that long when
|
data/Rakefile
CHANGED
data/example/redis-master.conf
CHANGED
@@ -50,7 +50,7 @@ loglevel notice
|
|
50
50
|
# Specify the log file name. Also 'stdout' can be used to force
|
51
51
|
# Redis to log on the standard output. Note that if you use standard
|
52
52
|
# output for logging but daemonize, logs will be sent to /dev/null
|
53
|
-
logfile
|
53
|
+
logfile ""
|
54
54
|
|
55
55
|
# To enable logging to the system logger, just set 'syslog-enabled' to yes,
|
56
56
|
# and optionally update the other syslog parameters to suit your needs.
|
data/example/redis-slave.conf
CHANGED
@@ -50,7 +50,7 @@ loglevel notice
|
|
50
50
|
# Specify the log file name. Also 'stdout' can be used to force
|
51
51
|
# Redis to log on the standard output. Note that if you use standard
|
52
52
|
# output for logging but daemonize, logs will be sent to /dev/null
|
53
|
-
logfile
|
53
|
+
logfile ""
|
54
54
|
|
55
55
|
# To enable logging to the system logger, just set 'syslog-enabled' to yes,
|
56
56
|
# and optionally update the other syslog parameters to suit your needs.
|
@@ -15,6 +15,8 @@ class Redis::Client
|
|
15
15
|
@failover_reconnect_wait = fetch_option(options, :failover_reconnect_wait) ||
|
16
16
|
DEFAULT_FAILOVER_RECONNECT_WAIT_SECONDS
|
17
17
|
|
18
|
+
Thread.new { watch_sentinel } if sentinel? && !fetch_option(options, :async)
|
19
|
+
|
18
20
|
initialize_without_sentinel(options)
|
19
21
|
end
|
20
22
|
|
@@ -43,7 +45,7 @@ class Redis::Client
|
|
43
45
|
deadline = @failover_reconnect_timeout.to_i + Time.now.to_f
|
44
46
|
begin
|
45
47
|
block.call
|
46
|
-
rescue Redis::CannotConnectError
|
48
|
+
rescue Redis::CannotConnectError, Errno::EHOSTDOWN, Errno::EHOSTUNREACH
|
47
49
|
raise if Time.now.to_f > deadline
|
48
50
|
sleep @failover_reconnect_wait
|
49
51
|
retry
|
@@ -66,7 +68,9 @@ class Redis::Client
|
|
66
68
|
end
|
67
69
|
|
68
70
|
def discover_master
|
71
|
+
attempts = 0
|
69
72
|
while true
|
73
|
+
attempts += 1
|
70
74
|
try_next_sentinel
|
71
75
|
|
72
76
|
begin
|
@@ -81,8 +85,9 @@ class Redis::Client
|
|
81
85
|
end
|
82
86
|
rescue Redis::CommandError => e
|
83
87
|
raise unless e.message.include?("IDONTKNOW")
|
84
|
-
rescue Redis::CannotConnectError
|
88
|
+
rescue Redis::CannotConnectError, Errno::EHOSTDOWN, Errno::EHOSTUNREACH => e
|
85
89
|
# failed to connect to current sentinel server
|
90
|
+
raise e if attempts > @sentinels_options.count
|
86
91
|
end
|
87
92
|
end
|
88
93
|
end
|
@@ -95,13 +100,13 @@ class Redis::Client
|
|
95
100
|
slaves_info = current_sentinel.sentinel("slaves", @master_name)
|
96
101
|
@slaves = slaves_info.map do |info|
|
97
102
|
info = Hash[*info]
|
98
|
-
::Redis.new
|
103
|
+
::Redis.new(@options.merge(:host => info['ip'], :port => info['port'], :driver => info[:driver]))
|
99
104
|
end
|
100
105
|
|
101
106
|
break
|
102
107
|
rescue Redis::CommandError => e
|
103
108
|
raise unless e.message.include?("IDONTKNOW")
|
104
|
-
rescue Redis::CannotConnectError
|
109
|
+
rescue Redis::CannotConnectError, Errno::EHOSTDOWN, Errno::EHOSTUNREACH
|
105
110
|
# failed to connect to current sentinel server
|
106
111
|
end
|
107
112
|
end
|
@@ -139,15 +144,42 @@ class Redis::Client
|
|
139
144
|
alias call_pipeline_without_readonly_protection call_pipeline
|
140
145
|
alias call_pipeline call_pipeline_with_readonly_protection
|
141
146
|
|
147
|
+
def watch_sentinel
|
148
|
+
while true
|
149
|
+
sentinel = Redis.new(@sentinels_options[0])
|
150
|
+
|
151
|
+
begin
|
152
|
+
sentinel.psubscribe("*") do |on|
|
153
|
+
on.pmessage do |pattern, channel, message|
|
154
|
+
next if channel != "+switch-master"
|
155
|
+
|
156
|
+
master_name, old_host, old_port, new_host, new_port = message.split(" ")
|
157
|
+
|
158
|
+
next if master_name != @master_name
|
159
|
+
|
160
|
+
@options.merge!(host: new_host, port: new_port.to_i)
|
161
|
+
|
162
|
+
@logger.debug "Failover: #{old_host}:#{old_port} => #{new_host}:#{new_port}" if @logger && @logger.debug?
|
163
|
+
|
164
|
+
disconnect
|
165
|
+
end
|
166
|
+
end
|
167
|
+
rescue Redis::CannotConnectError, Errno::EHOSTDOWN, Errno::EHOSTUNREACH
|
168
|
+
try_next_sentinel
|
169
|
+
sleep 1
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
142
174
|
private
|
143
175
|
def readonly_protection_with_timeout(method, *args, &block)
|
144
176
|
deadline = @failover_reconnect_timeout.to_i + Time.now.to_f
|
145
177
|
send(method, *args, &block)
|
146
178
|
rescue Redis::CommandError => e
|
147
179
|
if e.message.include? "READONLY You can't write against a read only slave."
|
180
|
+
reconnect
|
148
181
|
raise if Time.now.to_f > deadline
|
149
182
|
sleep @failover_reconnect_wait
|
150
|
-
reconnect
|
151
183
|
retry
|
152
184
|
else
|
153
185
|
raise
|
@@ -25,7 +25,7 @@ describe Redis::Client do
|
|
25
25
|
|
26
26
|
context "new instances" do
|
27
27
|
it "should parse sentinel options" do
|
28
|
-
expect(subject.instance_variable_get(:@sentinels_options)).to
|
28
|
+
expect(subject.instance_variable_get(:@sentinels_options)).to match_array [
|
29
29
|
{:host=>"localhost", :port=>26379},
|
30
30
|
{:host=>"localhost", :port=>26380},
|
31
31
|
{:host=>"localhost", :port=>26381}
|
@@ -5,7 +5,8 @@ require "eventmachine"
|
|
5
5
|
describe Redis::Client do
|
6
6
|
context "#auto_retry_with_timeout" do
|
7
7
|
subject { described_class.new(:failover_reconnect_timeout => 3,
|
8
|
-
|
8
|
+
:failover_reconnect_wait => 0.1,
|
9
|
+
:async => true) }
|
9
10
|
context "configured wait time" do
|
10
11
|
|
11
12
|
it "uses the wait time and blocks em" do
|
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-sentinel
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.5.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: 2014-
|
11
|
+
date: 2014-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: redis
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: eventmachine
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: em-synchrony
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: hiredis
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: another redis automatic master/slave failover solution for ruby by using
|
@@ -102,9 +102,7 @@ executables: []
|
|
102
102
|
extensions: []
|
103
103
|
extra_rdoc_files: []
|
104
104
|
files:
|
105
|
-
- .gitignore
|
106
|
-
- .ruby-gemset
|
107
|
-
- .ruby-version
|
105
|
+
- ".gitignore"
|
108
106
|
- CHANGELOG.md
|
109
107
|
- CONTRIBUTING.md
|
110
108
|
- Gemfile
|
@@ -137,17 +135,17 @@ require_paths:
|
|
137
135
|
- lib
|
138
136
|
required_ruby_version: !ruby/object:Gem::Requirement
|
139
137
|
requirements:
|
140
|
-
- -
|
138
|
+
- - ">="
|
141
139
|
- !ruby/object:Gem::Version
|
142
140
|
version: '0'
|
143
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
144
142
|
requirements:
|
145
|
-
- -
|
143
|
+
- - ">="
|
146
144
|
- !ruby/object:Gem::Version
|
147
145
|
version: '0'
|
148
146
|
requirements: []
|
149
147
|
rubyforge_project:
|
150
|
-
rubygems_version: 2.2.
|
148
|
+
rubygems_version: 2.2.2
|
151
149
|
signing_key:
|
152
150
|
specification_version: 4
|
153
151
|
summary: another redis automatic master/slave failover solution for ruby by using
|
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
redis-sentinel
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
ruby-2.0.0
|