Skip to content

Commit ba3dc87

Browse files
committed
More tests.
1 parent 746fab6 commit ba3dc87

File tree

3 files changed

+58
-12
lines changed

3 files changed

+58
-12
lines changed

cluster/test/async/redis/cluster_client.rb

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,27 @@
2222

2323
let(:cluster) {subject.new(endpoints)}
2424

25-
let(:key) {"sentinel-test:#{SecureRandom.hex(8)}"}
26-
let(:value) {"sentinel-test-value"}
25+
let(:key) {"cluster-test:#{SecureRandom.hex(8)}"}
26+
let(:value) {"cluster-test-value"}
27+
28+
it "can get a client for a given key" do
29+
slot = cluster.slot_for(key)
30+
client = cluster.client_for(slot)
31+
32+
expect(client).not.to be_nil
33+
end
2734

2835
it "can get and set values" do
36+
result = nil
37+
38+
pp key: key, slot: cluster.slot_for(key)
39+
2940
cluster.clients_for(key) do |client, key|
3041
client.set(key, value)
31-
expect(client.get(key)).to be == value
42+
43+
result = client.get(key)
3244
end
45+
46+
expect(result).to be == value
3347
end
3448
end

lib/async/redis/cluster_client.rb

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,35 +57,45 @@ def initialize(endpoints, **options)
5757
@shards = nil
5858
end
5959

60-
def clients_for(*keys, attempts: 3)
60+
def clients_for(*keys, role: :master, attempts: 3)
6161
slots = slots_for(keys)
6262

63-
slots.map do |slot, keys|
64-
yield client_for(slot), keys
63+
slots.each do |slot, keys|
64+
yield client_for(slot, role), keys
6565
end
6666
rescue ServerError => error
67+
Console.warn(self, error)
68+
6769
if error.message =~ /MOVED|ASK/
6870
reload_cluster!
6971

7072
attempts -= 1
7173

7274
retry if attempts > 0
75+
76+
raise
7377
else
7478
raise
7579
end
7680
end
7781

7882
def client_for(slot, role = :master)
79-
unless @nodes
83+
unless @shards
8084
reload_cluster!
8185
end
8286

8387
nodes = @shards.find(slot)
8488

89+
pp slot: slot, nodes: nodes
90+
8591
nodes = nodes.select{|node| node.role == role}
8692

93+
pp filtered_nodes: nodes
94+
8795
if node = nodes.sample
88-
node.client ||= Client.new(node.endpoint)
96+
pp sampled_node: node
97+
98+
return (node.client ||= Client.new(node.endpoint))
8999
end
90100
end
91101

@@ -117,6 +127,7 @@ def reload_cluster!(endpoints = @endpoints)
117127
shards.add(range, nodes)
118128
end
119129

130+
pp shards: shards
120131
@shards = shards
121132
# @endpoints = @endpoints | endpoints
122133

@@ -166,17 +177,19 @@ def reload_cluster!(endpoints = @endpoints)
166177
# This is the CRC16 algorithm used by Redis Cluster to hash keys.
167178
# Copied from https://github.com/antirez/redis-rb-cluster/blob/master/crc16.rb
168179
def crc16(bytes)
169-
crc = 0
180+
sum = 0
170181

171-
bytes.each_byte do |b|
172-
crc = ((crc << 8) & 0xffff) ^ XMODEM_CRC16_LOOKUP[((crc >> 8) ^ b) & 0xff]
182+
bytes.each_byte do |byte|
183+
sum = ((sum << 8) & 0xffff) ^ XMODEM_CRC16_LOOKUP[((sum >> 8) ^ byte) & 0xff]
173184
end
174185

175-
return crc
186+
return sum
176187
end
177188

178189
HASH_SLOTS = 16_384
179190

191+
public
192+
180193
# Return Redis::Client for a given key.
181194
# Modified from https://github.com/antirez/redis-rb-cluster/blob/master/cluster.rb#L104-L117
182195
def slot_for(key)

test/async/redis/cluster_client.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# frozen_string_literal: true
2+
3+
# Released under the MIT License.
4+
# Copyright, 2024, by Samuel Williams.
5+
6+
require 'async/redis/cluster_client'
7+
require 'sus/fixtures/async'
8+
require 'securerandom'
9+
10+
describe Async::Redis::ClusterClient do
11+
let(:client) {subject.new([])}
12+
13+
with "#slot_for" do
14+
it "can compute the correct slot for a given key" do
15+
expect(client.slot_for("helloworld")).to be == 2739
16+
expect(client.slot_for("test1234")).to be == 15785
17+
end
18+
end
19+
end

0 commit comments

Comments
 (0)