redis_failover 0.9.3 → 0.9.4
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/Changes.md +5 -0
- data/lib/redis_failover/node.rb +2 -2
- data/lib/redis_failover/node_manager.rb +29 -14
- data/lib/redis_failover/node_watcher.rb +1 -1
- data/lib/redis_failover/version.rb +1 -1
- metadata +4 -4
data/Changes.md
CHANGED
data/lib/redis_failover/node.rb
CHANGED
@@ -175,13 +175,13 @@ module RedisFailover
|
|
175
175
|
redis = new_client
|
176
176
|
yield redis
|
177
177
|
end
|
178
|
-
rescue => ex
|
178
|
+
rescue Exception => ex
|
179
179
|
raise NodeUnavailableError, "#{ex.class}: #{ex.message}", ex.backtrace
|
180
180
|
ensure
|
181
181
|
if redis
|
182
182
|
begin
|
183
183
|
redis.client.disconnect
|
184
|
-
rescue => ex
|
184
|
+
rescue Exception => ex
|
185
185
|
raise NodeUnavailableError, "#{ex.class}: #{ex.message}", ex.backtrace
|
186
186
|
end
|
187
187
|
end
|
@@ -10,7 +10,7 @@ module RedisFailover
|
|
10
10
|
include Util
|
11
11
|
|
12
12
|
# Number of seconds to wait before retrying bootstrap process.
|
13
|
-
TIMEOUT =
|
13
|
+
TIMEOUT = 3
|
14
14
|
# ZK Errors that the Node Manager cares about.
|
15
15
|
ZK_ERRORS = [
|
16
16
|
ZK::Exceptions::LockAssertionFailedError,
|
@@ -32,7 +32,6 @@ module RedisFailover
|
|
32
32
|
@znode = @options[:znode_path] || Util::DEFAULT_ZNODE_PATH
|
33
33
|
@manual_znode = ManualFailover::ZNODE_PATH
|
34
34
|
@mutex = Mutex.new
|
35
|
-
@shutdown = false
|
36
35
|
|
37
36
|
# Name for the znode that handles exclusive locking between multiple
|
38
37
|
# Node Manager processes. Whoever holds the lock will be considered
|
@@ -47,7 +46,6 @@ module RedisFailover
|
|
47
46
|
#
|
48
47
|
# @note This method does not return until the manager terminates.
|
49
48
|
def start
|
50
|
-
return if @shutdown
|
51
49
|
@queue = Queue.new
|
52
50
|
@leader = false
|
53
51
|
setup_zk
|
@@ -63,7 +61,6 @@ module RedisFailover
|
|
63
61
|
rescue *ZK_ERRORS => ex
|
64
62
|
logger.error("ZK error while attempting to manage nodes: #{ex.inspect}")
|
65
63
|
shutdown
|
66
|
-
sleep(TIMEOUT)
|
67
64
|
retry
|
68
65
|
end
|
69
66
|
|
@@ -78,10 +75,10 @@ module RedisFailover
|
|
78
75
|
|
79
76
|
# Performs a graceful shutdown of the manager.
|
80
77
|
def shutdown
|
81
|
-
@shutdown = true
|
82
78
|
@queue.clear
|
83
79
|
@queue << nil
|
84
80
|
@watchers.each(&:shutdown) if @watchers
|
81
|
+
sleep(TIMEOUT)
|
85
82
|
@zk.close! if @zk
|
86
83
|
@zk_lock = nil
|
87
84
|
end
|
@@ -115,7 +112,7 @@ module RedisFailover
|
|
115
112
|
|
116
113
|
# Handles periodic state reports from {RedisFailover::NodeWatcher} instances.
|
117
114
|
def handle_state_reports
|
118
|
-
while
|
115
|
+
while state_report = @queue.pop
|
119
116
|
# Ensure that we still have the master lock.
|
120
117
|
@zk_lock.assert!
|
121
118
|
|
@@ -238,9 +235,9 @@ module RedisFailover
|
|
238
235
|
|
239
236
|
# Discovers the current master and slave nodes.
|
240
237
|
def discover_nodes
|
241
|
-
@unavailable = []
|
242
238
|
nodes = @options[:nodes].map { |opts| Node.new(opts) }.uniq
|
243
|
-
@master = find_master(nodes)
|
239
|
+
@master = find_existing_master || find_master(nodes)
|
240
|
+
@unavailable = []
|
244
241
|
@slaves = nodes - [@master]
|
245
242
|
logger.info("Managing master (#{@master}) and slaves" +
|
246
243
|
" (#{@slaves.map(&:to_s).join(', ')})")
|
@@ -249,9 +246,32 @@ module RedisFailover
|
|
249
246
|
redirect_slaves_to(@master) if @master
|
250
247
|
end
|
251
248
|
|
249
|
+
# Seeds the initial node master from an existing znode config.
|
250
|
+
def find_existing_master
|
251
|
+
if data = @zk.get(@znode).first
|
252
|
+
nodes = symbolize_keys(decode(data))
|
253
|
+
master = node_from(nodes[:master])
|
254
|
+
logger.info("Master from existing config: #{master || 'none'}")
|
255
|
+
master
|
256
|
+
end
|
257
|
+
rescue ZK::Exceptions::NoNode
|
258
|
+
# blank slate, no last known master
|
259
|
+
nil
|
260
|
+
end
|
261
|
+
|
262
|
+
# Creates a Node instance from a string.
|
263
|
+
#
|
264
|
+
# @param [String] node_string a string representation of a node (e.g., host:port)
|
265
|
+
# @return [Node] the Node representation
|
266
|
+
def node_from(node_string)
|
267
|
+
return if node_string.nil?
|
268
|
+
host, port = node_string.split(':', 2)
|
269
|
+
Node.new(:host => host, :port => port, :password => @options[:password])
|
270
|
+
end
|
271
|
+
|
252
272
|
# Spawns the {RedisFailover::NodeWatcher} instances for each managed node.
|
253
273
|
def spawn_watchers
|
254
|
-
@watchers = [@master, @slaves, @unavailable].flatten.map do |node|
|
274
|
+
@watchers = [@master, @slaves, @unavailable].flatten.compact.map do |node|
|
255
275
|
NodeWatcher.new(self, node, @options[:max_failures] || 3)
|
256
276
|
end
|
257
277
|
@watchers.each(&:watch)
|
@@ -385,10 +405,5 @@ module RedisFailover
|
|
385
405
|
logger.error('Failed to perform manual failover, no candidate found.')
|
386
406
|
end
|
387
407
|
end
|
388
|
-
|
389
|
-
# @return [Boolean] true if still running, false otherwise
|
390
|
-
def running?
|
391
|
-
!@shutdown
|
392
|
-
end
|
393
408
|
end
|
394
409
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis_failover
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-08-
|
12
|
+
date: 2012-08-31 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
@@ -189,7 +189,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
189
189
|
version: '0'
|
190
190
|
segments:
|
191
191
|
- 0
|
192
|
-
hash: -
|
192
|
+
hash: -3042115734438994013
|
193
193
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
194
|
none: false
|
195
195
|
requirements:
|
@@ -198,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
198
198
|
version: '0'
|
199
199
|
segments:
|
200
200
|
- 0
|
201
|
-
hash: -
|
201
|
+
hash: -3042115734438994013
|
202
202
|
requirements: []
|
203
203
|
rubyforge_project:
|
204
204
|
rubygems_version: 1.8.23
|