Skip to content

Commit cc30984

Browse files
author
Daniel Solsona
committed
Add support for running sentinel API commands
1 parent 1ffdaa9 commit cc30984

File tree

3 files changed

+118
-2
lines changed

3 files changed

+118
-2
lines changed

lib/redis.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2539,6 +2539,34 @@ def pfmerge(dest_key, *source_key)
25392539
end
25402540
end
25412541

2542+
# Interact with the sentinel command (masters, master, slaves, failover)
2543+
#
2544+
# @param [String] subcommand e.g. `masters`, `master`, `slaves`
2545+
# @param [Array<String>] args depends on subcommand
2546+
# @return [Array<String>, Hash<String, String>, String] depends on subcommand
2547+
def sentinel(subcommand, *args)
2548+
subcommand = subcommand.to_s.downcase
2549+
synchronize do |client|
2550+
if subcommand == 'master'
2551+
client.call([:sentinel, subcommand] + args, &_hashify)
2552+
elsif subcommand == 'get-master-addr-by-name'
2553+
client.call([:sentinel, subcommand] + args)
2554+
else
2555+
client.call([:sentinel, subcommand] + args) do |reply|
2556+
if reply.kind_of?(Array)
2557+
new_reply = Array.new
2558+
reply.each do |r|
2559+
new_reply << _hashify.call(r)
2560+
end
2561+
new_reply
2562+
else
2563+
reply
2564+
end
2565+
end
2566+
end
2567+
end
2568+
end
2569+
25422570
def id
25432571
@original_client.id
25442572
end

test/sentinel_command_test.rb

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# encoding: UTF-8
2+
3+
require File.expand_path("helper", File.dirname(__FILE__))
4+
5+
class SentinalCommandsTest < Test::Unit::TestCase
6+
7+
include Helper::Client
8+
9+
def test_sentinel_command_master
10+
11+
handler = lambda do |id|
12+
{
13+
:sentinel => lambda do |command, *args|
14+
["name", "master1", "ip", "127.0.0.1"]
15+
end
16+
}
17+
end
18+
19+
RedisMock.start(handler.call(:s1), {}, 26381) do
20+
redis = Redis.new(:host => "127.0.0.1", :port => 26381)
21+
22+
result = redis.sentinel('master', 'master1')
23+
assert_equal result, { "name" => "master1", "ip" => "127.0.0.1" }
24+
end
25+
end
26+
27+
def test_sentinel_command_masters
28+
29+
handler = lambda do |id|
30+
{
31+
:sentinel => lambda do |command, *args|
32+
[%w[name master1 ip 127.0.0.1 port 6381], %w[name master1 ip 127.0.0.1 port 6382]]
33+
end
34+
}
35+
end
36+
37+
RedisMock.start(handler.call(:s1), {}, 26381) do
38+
redis = Redis.new(:host => "127.0.0.1", :port => 26381)
39+
40+
result = redis.sentinel('masters')
41+
assert_equal result[0], { "name" => "master1", "ip" => "127.0.0.1", "port" => "6381" }
42+
assert_equal result[1], { "name" => "master1", "ip" => "127.0.0.1", "port" => "6382" }
43+
end
44+
end
45+
46+
def test_sentinel_command_get_master_by_name
47+
48+
handler = lambda do |id|
49+
{
50+
:sentinel => lambda do |command, *args|
51+
["127.0.0.1", "6381"]
52+
end
53+
}
54+
end
55+
56+
RedisMock.start(handler.call(:s1), {}, 26381) do
57+
redis = Redis.new(:host => "127.0.0.1", :port => 26381)
58+
59+
result = redis.sentinel('get-master-addr-by-name', 'master1')
60+
assert_equal result, ["127.0.0.1", "6381"]
61+
end
62+
end
63+
64+
def test_sentinel_command_ckquorum
65+
handler = lambda do |id|
66+
{
67+
:sentinel => lambda do |command, *args|
68+
"+OK 2 usable Sentinels. Quorum and failover authorization can be reached"
69+
end
70+
}
71+
end
72+
73+
RedisMock.start(handler.call(:s1), {}, 26381) do
74+
redis = Redis.new(:host => "127.0.0.1", :port => 26381)
75+
76+
result = redis.sentinel('ckquorum', 'master1')
77+
assert_equal result, "OK 2 usable Sentinels. Quorum and failover authorization can be reached"
78+
end
79+
end
80+
end

test/support/redis_mock.rb

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,16 @@ def self.start(commands, options = {}, port = MOCK_PORT, &blk)
106106
break :close
107107
elsif response.is_a?(Array)
108108
session.write("*%d\r\n" % response.size)
109-
response.each do |e|
110-
session.write("$%d\r\n%s\r\n" % [e.length, e])
109+
110+
response.each do |resp|
111+
if resp.is_a?(Array)
112+
session.write("*%d\r\n" % resp.size)
113+
resp.each do |r|
114+
session.write("$%d\r\n%s\r\n" % [r.length, r])
115+
end
116+
else
117+
session.write("$%d\r\n%s\r\n" % [resp.length, resp])
118+
end
111119
end
112120
else
113121
session.write(response)

0 commit comments

Comments
 (0)