feat: non-blocking scan with progressive device discovery
Backend:
- asyncio.to_thread(_nmap_scan) — nmap no longer blocks the event loop
- Commit each discovered device immediately (previously one bulk commit at end)
- Update ScanRun.devices_found after each device so history panel shows live count
- broadcast_scan_update() pushes {type: scan_device_found} WS event per device
- Refactor broadcast_status to shared _broadcast() helper, adds type: "status" field
Frontend:
- useStatusPolling handles both WS message types (status / scan_device_found)
- canvasStore: scanEventTs + notifyScanDeviceFound() action
- PendingDevicesPanel auto-refreshes when WS scan event is received
This commit is contained in:
@@ -19,15 +19,27 @@ async def ws_status(websocket: WebSocket) -> None:
|
||||
_connections.remove(websocket)
|
||||
|
||||
|
||||
async def broadcast_status(node_id: str, status: str, checked_at: str, response_time_ms: int | None = None) -> None:
|
||||
payload = json.dumps({
|
||||
"node_id": node_id,
|
||||
"status": status,
|
||||
"checked_at": checked_at,
|
||||
"response_time_ms": response_time_ms,
|
||||
})
|
||||
async def _broadcast(payload: str) -> None:
|
||||
for conn in list(_connections):
|
||||
try:
|
||||
await conn.send_text(payload)
|
||||
except Exception:
|
||||
_connections.remove(conn)
|
||||
|
||||
|
||||
async def broadcast_status(node_id: str, status: str, checked_at: str, response_time_ms: int | None = None) -> None:
|
||||
await _broadcast(json.dumps({
|
||||
"type": "status",
|
||||
"node_id": node_id,
|
||||
"status": status,
|
||||
"checked_at": checked_at,
|
||||
"response_time_ms": response_time_ms,
|
||||
}))
|
||||
|
||||
|
||||
async def broadcast_scan_update(run_id: str, devices_found: int) -> None:
|
||||
await _broadcast(json.dumps({
|
||||
"type": "scan_device_found",
|
||||
"run_id": run_id,
|
||||
"devices_found": devices_found,
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user