home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
70.02k stars 29.09k forks source link

Blocking Import when loading custom component (pod_point) #121284

Open jamesonuk opened 2 weeks ago

jamesonuk commented 2 weeks ago

The problem

Logs report an issue with blocking import when loading custom component (https://github.com/mattrayner/pod-point-home-assistant-component). This integration is not using importlib to import dynamically which appears to be the intended check according to the docs

Where importlib being used in an integration you get a report like

Detected blocking call to import_module with args ('custom_components.better_thermostat.adapters.mqtt',) inside the event loop by custom integration 'better_thermostat' at custom_components/better_thermostat/adapters/delegate.py, line 16: self.adapter = import_module( (offender: /config/custom_components/better_thermostat/adapters/delegate.py, line 16: self.adapter = import_module(), please create a bug report at https://github.com/KartoffelToby/better_thermostat/issues For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#import_module Traceback (most recent call last): 

but see logs below this is reported in core and there is no dynamic import in the integration

What version of Home Assistant Core has the issue?

core-2024.7.0

What was the last working version of Home Assistant Core?

No response

What type of installation are you running?

Home Assistant Container

Integration causing the issue

Core

Link to integration documentation on our website

No response

Diagnostics information

No response

Example YAML snippet

No response

Anything in the logs that might be useful for us?

Logger: homeassistant.util.loop
Source: util/loop.py:77
First occurred: 09:01:33 (1 occurrences)
Last logged: 09:01:33

Detected blocking call to import_module with args ('custom_components.pod_point',) in /usr/src/homeassistant/homeassistant/loader.py, line 1050: ComponentProtocol, importlib.import_module(self.pkg_path) inside the event loop; This is causing stability issues. Please create a bug report at https://github.com/home-assistant/core/issues?q=is%3Aopen+is%3Aissue For developers, please see https://developers.home-assistant.io/docs/asyncio_blocking_operations/#import_module Traceback (most recent call last): File "<frozen runpy>", line 198, in _run_module_as_main File "<frozen runpy>", line 88, in _run_code File "/usr/src/homeassistant/homeassistant/__main__.py", line 223, in <module> sys.exit(main()) File "/usr/src/homeassistant/homeassistant/__main__.py", line 209, in main exit_code = runner.run(runtime_conf) File "/usr/src/homeassistant/homeassistant/runner.py", line 190, in run return loop.run_until_complete(setup_and_run_hass(runtime_config)) File "/usr/local/lib/python3.12/asyncio/base_events.py", line 674, in run_until_complete self.run_forever() File "/usr/local/lib/python3.12/asyncio/base_events.py", line 641, in run_forever self._run_once() File "/usr/local/lib/python3.12/asyncio/base_events.py", line 1990, in _run_once handle._run() File "/usr/local/lib/python3.12/asyncio/events.py", line 88, in _run self._context.run(self._callback, *self._args) File "/usr/src/homeassistant/homeassistant/setup.py", line 167, in async_setup_component result = await _async_setup_component(hass, domain, config) File "/usr/src/homeassistant/homeassistant/setup.py", line 322, in _async_setup_component component = await integration.async_get_component() File "/usr/src/homeassistant/homeassistant/loader.py", line 1002, in async_get_component comp = self._get_component() File "/usr/src/homeassistant/homeassistant/loader.py", line 1050, in _get_component ComponentProtocol, importlib.import_module(self.pkg_path)

Additional information

No response

elupus commented 2 weeks ago

It is doing some file io here: https://github.com/mattrayner/pod-point-home-assistant-component/blob/4320be5f60abea50776fba7511c2c6d1cae0643e/custom_components/pod_point/__init__.py#L90

Not sure that is the cause here though.

jamesonuk commented 2 weeks ago

It is doing some file io here: https://github.com/mattrayner/pod-point-home-assistant-component/blob/4320be5f60abea50776fba7511c2c6d1cae0643e/custom_components/pod_point/__init__.py#L90

Is it though? It is using 'pathlib' not 'os' and I thought that parent was essentially string manipulation? (and __FILE__ is not blocking either?)

Indeed I did attempt to replace pathlib with aiopath and you can't await parent.

The error does explicitly mention that it is call to import_module in loader.py that it is complaining about https://github.com/home-assistant/core/blob/9f839dbb77f0172388d7e6870e0f453d5b04d0ec/homeassistant/loader.py#L1050

I haven't looked at how HA is detecting blocking IO but I would have thought that dynamic importlib imports in custom components would be picked up when initialising the component not when trying to actually import it?

elupus commented 2 weeks ago

Path() does io. It may do listdirs and other stuff to find paths. PurePath() does not do io.

Just moving the calculation to a constant at module level would solve that.

But it is unclear if we catch those cases yet, so not sure that is what it is loving here.

jamesonuk commented 2 weeks ago

It is not my component, just looking to put in a PR to get these warnings out of my logs :) ` More for my info but is it doing IO? If I do

from pathlib import Path
x = Path("/some_other_path/test/xxx")
print (x.parent)

I get /some_other_path/test output as expected and that path definitely doesn't exist.

elupus commented 2 weeks ago

From docs on PurePath

You want to make sure that your code only manipulates paths without actually accessing the OS. In this case, instantiating one of the pure classes may be useful since those simply don’t have any OS-accessing operations

Standard path may do os level calls. Which may be blocking. But it os not guaranteed it is. Still a bad thing to use in async code.

But like i said, I'm not sure that is what we detect here.

elupus commented 2 weeks ago

Ps. Dont over complicate things (no need for aiofiles). Move stuff like this to module top level next to imports as a constant.

jamesonuk commented 2 weeks ago

As I said it is not my integration and looking to do the fewest changes. Did swap to PurePath and still get the warning so appears this is not the issue.

Might try and dig into the new blocking check code and see if I can see where this is actually trigger from

Floriszz commented 1 week ago

This, update from 2024.6.4 to 2024.7.1, caused 3 of my integration to stop working because this issue with the 'import_module'. Besides the above mentioned error. The integration page just says orange exclamation mark with 'not loaded', and no option to reload. Only delete. These integrations are;

After restore of version 2024.6.4 the integrations worked right away. Is not a solution but workaround for the time being.

elupus commented 1 week ago

@Floriszz you need to report that to the developers of those components. This issue is about pod_point.

Floriszz commented 1 week ago

@elupus , thanks I'll. I get the same error. So they all share the same problem. I will point them to here for a resolution direction.