Optimize add_job to skip double-deferral for @callback targets (#168198)

This commit is contained in:
Ariel Ebersberger
2026-04-15 18:50:33 +02:00
committed by GitHub
parent 1dc93a80c4
commit 533871babb
2 changed files with 8 additions and 6 deletions

View File

@@ -558,6 +558,14 @@ class HomeAssistant:
functools.partial(self.async_create_task, target, eager_start=True)
)
return
# For @callback targets, schedule directly via call_soon_threadsafe
# to avoid the extra deferral through _async_add_hass_job + call_soon.
# Check iscoroutinefunction to gracefully handle incorrectly labeled @callback functions.
if is_callback_check_partial(target) and not inspect.iscoroutinefunction(
target
):
self.loop.call_soon_threadsafe(target, *args)
return
self.loop.call_soon_threadsafe(
functools.partial(self._async_add_hass_job, HassJob(target), *args)
)

View File

@@ -894,9 +894,6 @@ async def test_add_job_callback(hass: HomeAssistant) -> None:
result.append(value)
await hass.async_add_executor_job(hass.add_job, my_callback, "called")
# Callback targets go through two deferrals: call_soon_threadsafe
# schedules _async_add_hass_job, which then call_soon's the actual target.
await hass.async_block_till_done()
await hass.async_block_till_done()
assert result == ["called"]
@@ -929,9 +926,6 @@ async def test_add_job_partial_callback(hass: HomeAssistant) -> None:
await hass.async_add_executor_job(
hass.add_job, functools.partial(my_callback, "partial"), 1
)
# Callback targets go through two deferrals: call_soon_threadsafe
# schedules _async_add_hass_job, which then call_soon's the actual target.
await hass.async_block_till_done()
await hass.async_block_till_done()
assert result == [("partial", 1)]