@@ -40,9 +40,10 @@ def empty?
4040 @size . zero?
4141 end
4242
43- # TODO: https://github.com/redis-rb/redis-cluster-client/issues/37
44- def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength
43+ # TODO: https://github.com/redis-rb/redis-cluster-client/issues/37 handle redirections
44+ def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
4545 all_replies = Array . new ( @size )
46+ errors = { }
4647 threads = @grouped . map do |k , v |
4748 Thread . new ( @client , k , v ) do |client , node_key , rows |
4849 Thread . pass
@@ -60,11 +61,15 @@ def execute # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Met
6061 raise ReplySizeError , "commands: #{ rows . size } , replies: #{ replies . size } " if rows . size != replies . size
6162
6263 rows . each_with_index { |row , idx | all_replies [ row . first ] = replies [ idx ] }
64+ rescue StandardError => e
65+ errors [ node_key ] = e
6366 end
6467 end
6568
6669 threads . each ( &:join )
67- all_replies
70+ return all_replies if errors . empty?
71+
72+ raise ::RedisClient ::Cluster ::ErrorCollection , errors
6873 end
6974 end
7075
@@ -185,10 +190,10 @@ def send_command(method, *command, **kwargs, &block) # rubocop:disable Metrics/A
185190 when 'acl' , 'auth' , 'bgrewriteaof' , 'bgsave' , 'quit' , 'save' , 'ping'
186191 @node . call_all ( method , *command , **kwargs , &block ) . first
187192 when 'flushall' , 'flushdb'
188- @node . call_primary ( method , *command , **kwargs , &block ) . first
193+ @node . call_primaries ( method , *command , **kwargs , &block ) . first
189194 when 'wait' then send_wait_command ( method , *command , **kwargs , &block )
190- when 'keys' then @node . call_replica ( method , *command , **kwargs , &block ) . flatten . sort
191- when 'dbsize' then @node . call_replica ( method , *command , **kwargs , &block ) . sum
195+ when 'keys' then @node . call_replicas ( method , *command , **kwargs , &block ) . flatten . sort
196+ when 'dbsize' then @node . call_replicas ( method , *command , **kwargs , &block ) . sum
192197 when 'scan' then _scan ( *command , **kwargs )
193198 when 'lastsave' then @node . call_all ( method , *command , **kwargs , &block ) . sort
194199 when 'role' then @node . call_all ( method , *command , **kwargs , &block )
@@ -206,14 +211,14 @@ def send_command(method, *command, **kwargs, &block) # rubocop:disable Metrics/A
206211 node = assign_node ( *command )
207212 try_send ( node , method , *command , **kwargs , &block )
208213 end
209- rescue RedisClient ::Cluster ::CommandErrorCollection => e
214+ rescue RedisClient ::Cluster ::ErrorCollection => e
210215 update_cluster_info! if e . errors . values . map ( &:class ) . any? ( ::RedisClient ::ConnectionError )
211216 raise
212217 end
213218
214219 def send_wait_command ( method , *command , retry_count : 3 , **kwargs , &block )
215- @node . call_primary ( method , *command , **kwargs , &block ) . sum
216- rescue RedisClient ::Cluster ::CommandErrorCollection => e
220+ @node . call_primaries ( method , *command , **kwargs , &block ) . sum
221+ rescue RedisClient ::Cluster ::ErrorCollection => e
217222 raise if retry_count <= 0 || e . errors . values . map ( &:message ) . grep ( /ERR WAIT cannot be used with replica instances/ ) . empty?
218223
219224 update_cluster_info!
@@ -246,13 +251,17 @@ def send_client_command(method, *command, **kwargs, &block)
246251 end
247252 end
248253
249- def send_cluster_command ( method , *command , **kwargs , &block )
254+ def send_cluster_command ( method , *command , **kwargs , &block ) # rubocop:disable Metrics/MethodLength
250255 subcommand = command [ 1 ] . to_s . downcase
251256 case subcommand
252257 when 'addslots' , 'delslots' , 'failover' , 'forget' , 'meet' , 'replicate' ,
253258 'reset' , 'set-config-epoch' , 'setslot'
254259 raise ::RedisClient ::Cluster ::OrchestrationCommandNotSupported , [ 'cluster' , subcommand ]
255260 when 'saveconfig' then @node . call_all ( method , *command , **kwargs , &block ) . first
261+ when 'getkeysinslot'
262+ raise ArgumentError , command . join ( ' ' ) if command . size != 4
263+
264+ find_node ( @node . find_node_key_of_replica ( command [ 2 ] ) ) . send ( method , *command , **kwargs , &block )
256265 else assign_node ( *command ) . send ( method , *command , **kwargs , &block )
257266 end
258267 end
@@ -262,7 +271,7 @@ def send_script_command(method, *command, **kwargs, &block)
262271 when 'debug' , 'kill'
263272 @node . call_all ( method , *command , **kwargs , &block ) . first
264273 when 'flush' , 'load'
265- @node . call_primary ( method , *command , **kwargs , &block ) . first
274+ @node . call_primaries ( method , *command , **kwargs , &block ) . first
266275 else assign_node ( *command ) . send ( method , *command , **kwargs , &block )
267276 end
268277 end
0 commit comments