Speed up coordinator refresh with parallel fetches and landscape lock#401
Merged
Speed up coordinator refresh with parallel fetches and landscape lock#401
Conversation
Periodic refreshes were taking ~2s because independent endpoints were awaited sequentially and parallel per-zone landscape lookups each fired a duplicate HTTP request to the same device-level endpoint. - Gather `devices` and `timer_programs` concurrently in the coordinator - Fan out per-device history/landscape bundles across all devices in parallel (previously the outer device loop was sequential) - Add a per-device `asyncio.Lock` around `_refresh_landscapes` so concurrent callers share one HTTP request instead of duplicating N
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Periodic coordinator refreshes were logging ~2s durations. Investigation
showed two causes that are independent of the B-hyve API's own latency:
devicesandtimer_programsareindependent endpoints but were awaited one after the other, and the
per-device history/landscape loop iterated devices serially.
get_landscape(device_id, zone_id)per zone in parallel. Each callroutes through
client._refresh_landscapes(device_id), which had nosingle-flight guard — so on a cold cache (every periodic refresh,
since
API_POLL_PERIODequals the 5-min coordinator interval) allN zones raced and fired N identical HTTP requests to the same
/landscape_descriptions/{device_id}endpoint.Changes:
coordinator._async_update_datanow gathersdevicesandtimer_programsconcurrently, and fans out per-device history +landscape bundles across all devices in parallel via a new
_fetch_device_bundlehelper.client._refresh_landscapesnow holds a per-deviceasyncio.Lock.Concurrent callers for the same device share one HTTP request; the
followers see the fresh timestamp on re-entry and return from cache.
Expected impact: a single-device account should see refresh time drop
from roughly 3 serial roundtrips to roughly 1 (bounded by the slowest
single roundtrip), plus the elimination of N-1 duplicate landscape
requests per zone. Multi-device accounts benefit further from the
cross-device parallelism.
Test plan
./scripts/test— 153 passed, 5 skipped./scripts/lint— all checks passedtest_concurrent_calls_dedupe_to_single_requestin
tests/test_client.pythat proves concurrentget_landscapecalls for the same device now fire a single HTTP request