Skip to content

perf(coordinator): parallelize RCI fetches with bounded, staged concurrency#39

Merged
cataseven merged 2 commits intocataseven:mainfrom
ABovsh:patch-2
Apr 13, 2026
Merged

perf(coordinator): parallelize RCI fetches with bounded, staged concurrency#39
cataseven merged 2 commits intocataseven:mainfrom
ABovsh:patch-2

Conversation

@ABovsh
Copy link
Copy Markdown
Contributor

@ABovsh ABovsh commented Apr 12, 2026

Summary

Replace the sequential fetch loop in KeeneticCoordinator._async_update_data with bounded, staged parallelism. This shortens each coordinator tick on mid-range Keenetic hardware and, on slower routers or busier networks, helps the coordinator stay within FAST_SCAN_INTERVAL instead of overrunning it (which causes Home Assistant to silently skip ticks and roughly double the observed update cadence).

This is a self-contained change: only the body of _async_update_data is touched. No public API, no entity descriptions, no other files.

What this PR does

The fetches are split into three dependency stages, each internally parallel, with a shared asyncio.Semaphore(4) capping concurrent in-flight RCI calls:

Stage Calls Depends on
1 system_info, current_version, available_version, interfaces, clients, mesh_nodes, client_stats, host_policies, ndns_info, usb_storage, interface_stats, ping_check_status
  • Hardware Protection: Concurrency is bounded to 4 because Keenetic's RCI is a single HTTP surface served by a modest router CPU. Firing 15+ requests fully in parallel risks 503s or auth contention on lower-end hardware.
  • Fault Tolerance: All asyncio.gather calls use return_exceptions=True, and a small _ok() helper normalizes any failed fetch into a safe default of the correct shape. As a side effect, a single flaky endpoint no longer kills the entire update tick — that data point is simply absent for one cycle, and the next tick retries it.
  • Logic Maintained: WAN enrichment, role labeling, throughput-delta calculation, new-client detection, and the final return dict are byte-for-byte unchanged.

ABovsh and others added 2 commits April 12, 2026 21:36
…rrency

# perf(coordinator): parallelize RCI fetches with bounded, staged concurrency

## Summary

Replace the sequential fetch loop in `KeeneticCoordinator._async_update_data`
with bounded, staged parallelism. This shortens each coordinator tick on
mid-range Keenetic hardware and, on slower routers or busier networks,
helps the coordinator stay within `FAST_SCAN_INTERVAL` instead of
overrunning it (which causes Home Assistant to silently skip ticks and
roughly double the observed update cadence).

This is a self-contained change: only the body of `_async_update_data`
is touched. No public API, no entity descriptions, no other files.

## What this PR does

The fetches are split into three dependency stages, each internally
parallel, with a shared `asyncio.Semaphore(4)` capping concurrent
in-flight RCI calls:

| Stage | Calls | Depends on |
|---|---|---|
| **1** | `system_info`, `current_version`, `available_version`, `interfaces`, `clients`, `mesh_nodes`, `client_stats`, `host_policies`, `ndns_info`, `usb_storage`, `interface_stats`, `ping_check_status` | — |
| **2** | `wifi`, `wireguard`, `vpn_tunnels`, `wan_status`, `wan_interfaces`, `traffic_stats`, `port_info` | stage 1 (`interfaces`) |
| **3** | `wifi_passwords` (per missing SSID), `mesh_usb` (per connected node) | stages 1–2 |

Concurrency is bounded to 4 because Keenetic's RCI is a single HTTP
surface served by a modest router CPU; firing 15+ requests fully in
parallel risks 503s or auth contention on lower-end hardware.

All `gather` calls use `return_exceptions=True`, and a small `_ok()`
helper normalises any failed fetch into a safe default of the correct
shape. As a side effect, a single flaky endpoint no longer kills the
entire update tick — that data point is simply absent for one cycle
and the next tick retries it.

WAN enrichment, role labelling, throughput-delta calculation, the
new-client detection, and the final return dict are byte-for-byte
unchanged.
@cataseven cataseven merged commit e369099 into cataseven:main Apr 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants