@@ -292,15 +292,17 @@ def get_node(self, node: str) -> NodeInfo | None:
292292
293293 def get_all_nodes (self ) -> list [NodeInfo ]:
294294 """
295- Get all nodes from the redis
295+ Get all nodes from the redis using non-blocking scan.
296+ Guarantees unique list of NodeInfo.
296297 """
297- # check the map in redis
298- nodes : dict [str , str ] = self .rdb .hgetall (self .node_info_map ) # type: ignore
299- if not nodes :
300- return []
301-
302- # key: hostname of the node, value: node info
303- return [NodeInfo .model_validate_json (node ) for node in nodes .values ()]
298+ # Collect into dict first to match original deduplication behavior
299+ nodes_dict = {}
300+ for hostname_bin , node_json in self .rdb .hscan_iter (self .node_info_map ):
301+ if node_json :
302+ hostname = hostname_bin .decode () if isinstance (hostname_bin , bytes ) else hostname_bin
303+ nodes_dict [hostname ] = NodeInfo .model_validate_json (node_json )
304+
305+ return list (nodes_dict .values ())
304306
305307 def dispatch_rpc_job (
306308 self ,
@@ -652,8 +654,10 @@ def get_command_list(r):
652654 )
653655
654656 def _get_all_job_id (self ):
655- keys : list [bytes ] = self .rdb .keys (f"{ Job .redis_job_namespace_prefix } *" ) # type: ignore
656- return [k .decode ().split (":" )[- 1 ] for k in keys ]
657+ # Use scan_iter instead of keys() to avoid blocking Redis main thread
658+ # Add set() to ensure unique IDs if Redis returns duplicates during scanning
659+ keys = self .rdb .scan_iter (match = f"{ Job .redis_job_namespace_prefix } *" )
660+ return list (set (k .decode ().split (":" )[- 1 ] for k in keys ))
657661
658662 def _get_job_id_by_status (self , state : str , q_name : str ):
659663 """
0 commit comments