@@ -16,42 +16,47 @@ class Cluster
1616 def initialize ( config , pool : nil , concurrency : nil , **kwargs )
1717 @config = config
1818 @concurrent_worker = ::RedisClient ::Cluster ::ConcurrentWorker . create ( **( concurrency || { } ) )
19- @router = ::RedisClient ::Cluster ::Router . new ( config , @concurrent_worker , pool : pool , **kwargs )
2019 @command_builder = config . command_builder
20+
21+ @pool = pool
22+ @kwargs = kwargs
23+ @router = nil
24+ @mutex = Mutex . new
2125 end
2226
2327 def inspect
24- "#<#{ self . class . name } #{ @router . node_keys . join ( ', ' ) } >"
28+ node_keys = @router . nil? ? @config . startup_nodes . keys : router . node_keys
29+ "#<#{ self . class . name } #{ node_keys . join ( ', ' ) } >"
2530 end
2631
2732 def call ( *args , **kwargs , &block )
2833 command = @command_builder . generate ( args , kwargs )
29- @ router. send_command ( :call_v , command , &block )
34+ router . send_command ( :call_v , command , &block )
3035 end
3136
3237 def call_v ( command , &block )
3338 command = @command_builder . generate ( command )
34- @ router. send_command ( :call_v , command , &block )
39+ router . send_command ( :call_v , command , &block )
3540 end
3641
3742 def call_once ( *args , **kwargs , &block )
3843 command = @command_builder . generate ( args , kwargs )
39- @ router. send_command ( :call_once_v , command , &block )
44+ router . send_command ( :call_once_v , command , &block )
4045 end
4146
4247 def call_once_v ( command , &block )
4348 command = @command_builder . generate ( command )
44- @ router. send_command ( :call_once_v , command , &block )
49+ router . send_command ( :call_once_v , command , &block )
4550 end
4651
4752 def blocking_call ( timeout , *args , **kwargs , &block )
4853 command = @command_builder . generate ( args , kwargs )
49- @ router. send_command ( :blocking_call_v , command , timeout , &block )
54+ router . send_command ( :blocking_call_v , command , timeout , &block )
5055 end
5156
5257 def blocking_call_v ( timeout , command , &block )
5358 command = @command_builder . generate ( command )
54- @ router. send_command ( :blocking_call_v , command , timeout , &block )
59+ router . send_command ( :blocking_call_v , command , timeout , &block )
5560 end
5661
5762 def scan ( *args , **kwargs , &block )
@@ -60,31 +65,31 @@ def scan(*args, **kwargs, &block)
6065 seed = Random . new_seed
6166 cursor = ZERO_CURSOR_FOR_SCAN
6267 loop do
63- cursor , keys = @ router. scan ( 'SCAN' , cursor , *args , seed : seed , **kwargs )
68+ cursor , keys = router . scan ( 'SCAN' , cursor , *args , seed : seed , **kwargs )
6469 keys . each ( &block )
6570 break if cursor == ZERO_CURSOR_FOR_SCAN
6671 end
6772 end
6873
6974 def sscan ( key , *args , **kwargs , &block )
70- node = @ router. assign_node ( [ 'SSCAN' , key ] )
71- @ router. try_delegate ( node , :sscan , key , *args , **kwargs , &block )
75+ node = router . assign_node ( [ 'SSCAN' , key ] )
76+ router . try_delegate ( node , :sscan , key , *args , **kwargs , &block )
7277 end
7378
7479 def hscan ( key , *args , **kwargs , &block )
75- node = @ router. assign_node ( [ 'HSCAN' , key ] )
76- @ router. try_delegate ( node , :hscan , key , *args , **kwargs , &block )
80+ node = router . assign_node ( [ 'HSCAN' , key ] )
81+ router . try_delegate ( node , :hscan , key , *args , **kwargs , &block )
7782 end
7883
7984 def zscan ( key , *args , **kwargs , &block )
80- node = @ router. assign_node ( [ 'ZSCAN' , key ] )
81- @ router. try_delegate ( node , :zscan , key , *args , **kwargs , &block )
85+ node = router . assign_node ( [ 'ZSCAN' , key ] )
86+ router . try_delegate ( node , :zscan , key , *args , **kwargs , &block )
8287 end
8388
8489 def pipelined ( exception : true )
8590 seed = @config . use_replica? && @config . replica_affinity == :random ? nil : Random . new_seed
8691 pipeline = ::RedisClient ::Cluster ::Pipeline . new (
87- @ router,
92+ router ,
8893 @command_builder ,
8994 @concurrent_worker ,
9095 exception : exception ,
@@ -99,48 +104,56 @@ def pipelined(exception: true)
99104
100105 def multi ( watch : nil )
101106 if watch . nil? || watch . empty?
102- transaction = ::RedisClient ::Cluster ::Transaction . new ( @ router, @command_builder )
107+ transaction = ::RedisClient ::Cluster ::Transaction . new ( router , @command_builder )
103108 yield transaction
104109 return transaction . execute
105110 end
106111
107- ::RedisClient ::Cluster ::OptimisticLocking . new ( @ router) . watch ( watch ) do |c , slot , asking |
112+ ::RedisClient ::Cluster ::OptimisticLocking . new ( router ) . watch ( watch ) do |c , slot , asking |
108113 transaction = ::RedisClient ::Cluster ::Transaction . new (
109- @ router, @command_builder , node : c , slot : slot , asking : asking
114+ router , @command_builder , node : c , slot : slot , asking : asking
110115 )
111116 yield transaction
112117 transaction . execute
113118 end
114119 end
115120
116121 def pubsub
117- ::RedisClient ::Cluster ::PubSub . new ( @ router, @command_builder )
122+ ::RedisClient ::Cluster ::PubSub . new ( router , @command_builder )
118123 end
119124
120125 def with ( ...)
121126 raise NotImplementedError , 'No way to use'
122127 end
123128
124129 def close
130+ @router &.close
125131 @concurrent_worker . close
126- @router . close
127132 nil
128133 end
129134
130135 private
131136
137+ def router
138+ return @router unless @router . nil?
139+
140+ @mutex . synchronize do
141+ @router ||= ::RedisClient ::Cluster ::Router . new ( @config , @concurrent_worker , pool : @pool , **@kwargs )
142+ end
143+ end
144+
132145 def method_missing ( name , *args , **kwargs , &block )
133- if @ router. command_exists? ( name )
146+ if router . command_exists? ( name )
134147 args . unshift ( name )
135148 command = @command_builder . generate ( args , kwargs )
136- return @ router. send_command ( :call_v , command , &block )
149+ return router . send_command ( :call_v , command , &block )
137150 end
138151
139152 super
140153 end
141154
142155 def respond_to_missing? ( name , include_private = false )
143- return true if @ router. command_exists? ( name )
156+ return true if router . command_exists? ( name )
144157
145158 super
146159 end
0 commit comments