Skip to content

Commit 2309c33

Browse files
authored
refactor: slot-node mappings implementation (#186)
1 parent 52bdfb7 commit 2309c33

File tree

4 files changed

+28
-19
lines changed

4 files changed

+28
-19
lines changed

.github/workflows/test.yaml

+4-3
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ jobs:
4343
- '6.2.7'
4444
ruby:
4545
- '3.2'
46-
- '3.1'
47-
- '3.0'
4846
- '2.7'
4947
driver:
5048
- 'ruby'
@@ -365,7 +363,10 @@ jobs:
365363
strategy:
366364
fail-fast: false
367365
matrix:
368-
mode: ['single', 'excessive_pipelining', 'pipelining_in_moderation']
366+
mode:
367+
- single
368+
- excessive_pipelining
369+
- pipelining_in_moderation
369370
runs-on: ubuntu-latest
370371
env:
371372
REDIS_VERSION: '7.0.5'

lib/redis_client/cluster/node.rb

+20-14
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ class Node
1818
MAX_STARTUP_SAMPLE = 37
1919
MAX_THREADS = Integer(ENV.fetch('REDIS_CLIENT_MAX_THREADS', 5))
2020
IGNORE_GENERIC_CONFIG_KEYS = %i[url host port path].freeze
21-
SLOT_OPTIMIZATION_STRING = '0' * SLOT_SIZE
2221

2322
ReloadNeeded = Class.new(::RedisClient::Error)
2423

@@ -37,27 +36,36 @@ def replica?
3736
end
3837
end
3938

40-
Slot = Struct.new('StringArray', :string, :elements, keyword_init: true) do
39+
class CharArray
40+
BASE = ''
41+
PADDING = '0'
42+
43+
def initialize(size, elements)
44+
@elements = elements
45+
@string = String.new(BASE, encoding: Encoding::BINARY, capacity: size)
46+
size.times { @string << PADDING }
47+
end
48+
4149
def [](index)
4250
raise IndexError if index < 0
43-
return if index >= string.bytesize
51+
return if index >= @string.bytesize
4452

45-
elements[string.getbyte(index)]
53+
@elements[@string.getbyte(index)]
4654
end
4755

4856
def []=(index, element)
4957
raise IndexError if index < 0
50-
return if index >= string.bytesize
58+
return if index >= @string.bytesize
5159

52-
pos = elements.find_index(element) # O(N)
60+
pos = @elements.find_index(element) # O(N)
5361
if pos.nil?
54-
raise(RangeError, 'full of elements') if elements.size >= 256
62+
raise(RangeError, 'full of elements') if @elements.size >= 256
5563

56-
pos = elements.size
57-
elements << element
64+
pos = @elements.size
65+
@elements << element
5866
end
5967

60-
string.setbyte(index, pos)
68+
@string.setbyte(index, pos)
6169
end
6270
end
6371

@@ -268,10 +276,8 @@ def build_slot_node_mappings(node_info_list)
268276
def make_array_for_slot_node_mappings(node_info_list)
269277
return Array.new(SLOT_SIZE) if node_info_list.count(&:primary?) > 256
270278

271-
::RedisClient::Cluster::Node::Slot.new(
272-
string: String.new(SLOT_OPTIMIZATION_STRING, encoding: Encoding::BINARY, capacity: SLOT_SIZE),
273-
elements: node_info_list.select(&:primary?).map(&:node_key)
274-
)
279+
primary_node_keys = node_info_list.select(&:primary?).map(&:node_key)
280+
::RedisClient::Cluster::Node::CharArray.new(SLOT_SIZE, primary_node_keys)
275281
end
276282

277283
def build_replication_mappings(node_info_list) # rubocop:disable Metrics/AbcSize

test/cluster_controller.rb

+2
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,8 @@ def finish_resharding(slot:, src_node_key:, dest_node_key:) # rubocop:disable Me
145145
raise if e.message != 'ERR Please use SETSLOT only with masters.'
146146
# how weird, ignore
147147
end
148+
149+
wait_replication_delay(@clients, replica_size: @replica_size, timeout: @timeout)
148150
end
149151

150152
def scale_out(primary_url:, replica_url:) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity

test/redis_client/cluster/test_node.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ def test_make_array_for_slot_node_mappings_optimized
382382

383383
want = node_info_list.first.node_key
384384
got = @test_node.send(:make_array_for_slot_node_mappings, node_info_list)
385-
assert_instance_of(Struct::StringArray, got)
385+
assert_instance_of(::RedisClient::Cluster::Node::CharArray, got)
386386
::RedisClient::Cluster::Node::SLOT_SIZE.times do |i|
387387
got[i] = want
388388
assert_equal(want, got[i], "Case: #{i}")
@@ -415,7 +415,7 @@ def test_make_array_for_slot_node_mappings_max_shard_size
415415
end
416416

417417
got = @test_node.send(:make_array_for_slot_node_mappings, node_info_list)
418-
assert_instance_of(Struct::StringArray, got)
418+
assert_instance_of(::RedisClient::Cluster::Node::CharArray, got)
419419

420420
::RedisClient::Cluster::Node::SLOT_SIZE.times { |i| got[i] = node_info_list.first.node_key }
421421

0 commit comments

Comments
 (0)