Skip to content

Commit 5483b27

Browse files
committed
feat: improve prompt synchronization in Netmiko driver and replace Redis KEYS with scan_iter to avoid blocking
1 parent 12e3d99 commit 5483b27

3 files changed

Lines changed: 17 additions & 16 deletions

File tree

netpulse/plugins/drivers/netmiko/__init__.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -422,9 +422,6 @@ def config(self, session: BaseConnection, config: list[str]) -> list[DriverExecu
422422
)
423423
)
424424
break
425-
finally:
426-
# Maintain prompt synchronization to handle sub-view changes
427-
session.set_base_prompt()
428425

429426
# 3. Post-execution operations (Commit/Save)
430427
if commit := self._commit(session):

netpulse/services/manager.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -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
"""

netpulse/services/rediz.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,12 @@ def unregister(self, task_id: str):
192192
log.info(f"Detached Task {task_id} removed from Registry.")
193193

194194
def list_all(self) -> dict:
195-
"""List all registered tasks."""
195+
"""List all registered tasks using non-blocking scan."""
196196
import json
197197

198-
raw = self.rdb.hgetall(self.KEY)
199198
result = {}
200-
for k, v in raw.items():
199+
# Use hscan_iter to avoid blocking Redis with large registries
200+
for k, v in self.rdb.hscan_iter(self.KEY):
201201
key = k.decode("utf-8") if isinstance(k, bytes) else k
202202
val = v.decode("utf-8") if isinstance(v, bytes) else v
203203
result[key] = json.loads(val)

0 commit comments

Comments
 (0)