Add support for eager tasks (#111425)

* Add support for eager tasks

python 3.12 supports eager tasks

reading:
https://docs.python.org/3/library/asyncio-task.html#eager-task-factory
https://github.com/python/cpython/issues/97696

There are lots of places were we are unlikely to suspend, but we might
suspend so creating a task makes sense

* reduce

* revert entity

* revert

* coverage

* coverage

* coverage

* coverage

* fix test
This commit is contained in:
J. Nick Koston 2024-02-26 06:36:46 -10:00 committed by GitHub
parent 93cc6e0f36
commit 67e356904b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 162 additions and 18 deletions

View file

@ -1,5 +1,6 @@
"""Tests for async util methods from Python source."""
import asyncio
import sys
import time
from unittest.mock import MagicMock, Mock, patch
@ -246,3 +247,53 @@ async def test_callback_is_always_scheduled(hass: HomeAssistant) -> None:
hasync.run_callback_threadsafe(hass.loop, callback)
mock_call_soon_threadsafe.assert_called_once()
@pytest.mark.skipif(sys.version_info < (3, 12), reason="Test requires Python 3.12+")
async def test_create_eager_task_312(hass: HomeAssistant) -> None:
"""Test create_eager_task schedules a task eagerly in the event loop.
For Python 3.12+, the task is scheduled eagerly in the event loop.
"""
events = []
async def _normal_task():
events.append("normal")
async def _eager_task():
events.append("eager")
task1 = hasync.create_eager_task(_eager_task())
task2 = asyncio.create_task(_normal_task())
assert events == ["eager"]
await asyncio.sleep(0)
assert events == ["eager", "normal"]
await task1
await task2
@pytest.mark.skipif(sys.version_info >= (3, 12), reason="Test requires < Python 3.12")
async def test_create_eager_task_pre_312(hass: HomeAssistant) -> None:
"""Test create_eager_task schedules a task in the event loop.
For older python versions, the task is scheduled normally.
"""
events = []
async def _normal_task():
events.append("normal")
async def _eager_task():
events.append("eager")
task1 = hasync.create_eager_task(_eager_task())
task2 = asyncio.create_task(_normal_task())
assert events == []
await asyncio.sleep(0)
assert events == ["eager", "normal"]
await task1
await task2