Skip to content

Commit 559bf53

Browse files
authored
feat: support compatibility with redis gem (#84)
1 parent 99fbc22 commit 559bf53

File tree

7 files changed

+62
-0
lines changed

7 files changed

+62
-0
lines changed

lib/redis_client/cluster.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ class Cluster
1111

1212
def initialize(config, pool: nil, **kwargs)
1313
@router = ::RedisClient::Cluster::Router.new(config, pool: pool, **kwargs)
14+
@command_builder = config.command_builder
1415
end
1516

1617
def inspect
@@ -71,5 +72,25 @@ def close
7172
@router.node.call_all(:close)
7273
nil
7374
end
75+
76+
private
77+
78+
def method_missing(name, *args, **kwargs)
79+
if @router.command_exists?(name)
80+
args.unshift(name)
81+
args = @command_builder.generate!(args, kwargs)
82+
@router.send_command(:call, *args)
83+
else
84+
super
85+
end
86+
end
87+
88+
def respond_to_missing?(name, include_private = false)
89+
if @router.command_exists?(name)
90+
true
91+
else
92+
super
93+
end
94+
end
7495
end
7596
end

lib/redis_client/cluster/command.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ def should_send_to_replica?(command)
5555
dig_details(command, :readonly)
5656
end
5757

58+
def exists?(name)
59+
@details.key?(name.to_s.downcase)
60+
end
61+
5862
private
5963

6064
def pick_details(details)

lib/redis_client/cluster/router.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ def find_node(node_key, retry_count: 3)
142142
retry
143143
end
144144

145+
def command_exists?(name)
146+
@command.exists?(name)
147+
end
148+
145149
private
146150

147151
def send_wait_command(method, *args, retry_count: 3, **kwargs, &block)

lib/redis_client/cluster_config.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require 'redis_client'
55
require 'redis_client/cluster'
66
require 'redis_client/cluster/node_key'
7+
require 'redis_client/command_builder'
78

89
class RedisClient
910
class ClusterConfig
@@ -19,11 +20,14 @@ class ClusterConfig
1920

2021
InvalidClientConfigError = Class.new(::RedisClient::Error)
2122

23+
attr_reader :command_builder
24+
2225
def initialize(nodes: DEFAULT_NODES, replica: false, fixed_hostname: '', **client_config)
2326
@replica = true & replica
2427
@fixed_hostname = fixed_hostname.to_s
2528
@node_configs = build_node_configs(nodes.dup)
2629
client_config = client_config.reject { |k, _| IGNORE_GENERIC_CONFIG_KEYS.include?(k) }
30+
@command_builder = client_config.fetch(:command_builder, ::RedisClient::CommandBuilder)
2731
@client_config = merge_generic_config(client_config, @node_configs)
2832
@mutex = Mutex.new
2933
end

test/redis_client/cluster/test_command.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,25 @@ def test_should_send_to_replica?
115115
end
116116
end
117117

118+
def test_exists?
119+
cmd = ::RedisClient::Cluster::Command.load(@raw_clients)
120+
[
121+
{ name: 'ping', want: true },
122+
{ name: :ping, want: true },
123+
{ name: 'PING', want: true },
124+
{ name: 'densaugeo', want: false },
125+
{ name: :densaugeo, want: false },
126+
{ name: 'DENSAUGEO', want: false },
127+
{ name: '', want: false },
128+
{ name: 0, want: false },
129+
{ name: nil, want: false }
130+
].each_with_index do |c, idx|
131+
msg = "Case: #{idx}"
132+
got = cmd.exists?(c[:name])
133+
assert_equal(c[:want], got, msg)
134+
end
135+
end
136+
118137
def test_pick_details
119138
keys = %i[first_key_position write readonly].freeze
120139
[

test/redis_client/test_cluster.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@ def test_dedicated_commands
182182
end
183183
end
184184

185+
def test_compatibility_with_redis_gem
186+
assert_equal('OK', @client.set('foo', 100))
187+
assert_equal('100', @client.get('foo'))
188+
assert_raises(NoMethodError) { @client.densaugeo('1m') }
189+
end
190+
185191
private
186192

187193
def wait_for_replication

test/redis_client/test_cluster_config.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ def test_dup
9090
refute_equal(orig.object_id, copy.object_id)
9191
end
9292

93+
def test_command_builder
94+
assert_equal(::RedisClient::CommandBuilder, ::RedisClient::ClusterConfig.new.command_builder)
95+
end
96+
9397
def test_build_node_configs
9498
config = ::RedisClient::ClusterConfig.new
9599
[

0 commit comments

Comments
 (0)