-
Notifications
You must be signed in to change notification settings - Fork 34
Description
Describe the bug
The Problem: The integration wraps the synchronous FlightRadar24API library (which uses the requests library) inside async_add_executor_job. This results in blocking I/O on SyncWorker threads.
On a 10-second polling interval, any network latency or API hang causes these threads to lock up. While these calls usually resolve in 0.2–0.3s, latency spikes (which I have observed up to 3.4s) cause a cascade failure. Because Home Assistant has a finite number of executor threads, these "zombie threads" quickly exhaust the pool, starving other cloud-based integrations and causing system-wide Unclosed connection or Session is closed errors.
Code Analysis: In init.py, the setup and coordinator rely on blocking executor jobs:
await hass.async_add_executor_job(client.login, username, password)
# ...
await coordinator.async_config_entry_first_refresh()Why this blocks the whole system:
- No Async timeouts: Synchronous requests do not respect Home Assistant’s async timeouts, holding threads indefinitely during a hang.
- Worker Starvation: Once the SyncWorker pool is saturated with socket.read tasks, no other synchronous tasks in the system can trigger.
- Shutdown Deadlock: During shutdown, HA hangs while waiting for these blocking threads to join, eventually requiring a hard process kill.
Logs
The traceback confirms the system is hanging at the socket level inside requests within that executor job:
File "/usr/local/lib/python3.13/site-packages/FlightRadar24/api.py", line 429, in get_flight_details
response = APIRequest(...)
File "/usr/local/lib/python3.13/site-packages/requests/api.py", line 73, in get
...
File "/usr/local/lib/python3.13/socket.py", line 719, in readintoSuggested Fix:
- Primary Fix: Migrate the underlying FlightRadar24 library from requests to aiohttp. This allows the integration to stay on the MainThread using async_with aiohttp.ClientSession().
- Secondary/Immediate Fix: If remaining synchronous, wrap the executor_job with a strict asyncio.wait_for timeout and ensure the API client is initialized with a short timeout (e.g., 5s) to prevent threads from hanging.