Remove rest api service call timeout (#104709)

This commit is contained in:
Martin Hjelmare 2023-11-29 14:46:19 +01:00 committed by GitHub
parent 09d7679818
commit e884933dbd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 16 deletions

View file

@ -390,17 +390,14 @@ class APIDomainServicesView(HomeAssistantView):
) )
try: try:
async with timeout(SERVICE_WAIT_TIMEOUT): # shield the service call from cancellation on connection drop
# shield the service call from cancellation on connection drop await shield(
await shield( hass.services.async_call(
hass.services.async_call( domain, service, data, blocking=True, context=context
domain, service, data, blocking=True, context=context
)
) )
)
except (vol.Invalid, ServiceNotFound) as ex: except (vol.Invalid, ServiceNotFound) as ex:
raise HTTPBadRequest() from ex raise HTTPBadRequest() from ex
except TimeoutError:
pass
finally: finally:
cancel_listen() cancel_listen()

View file

@ -1,9 +1,10 @@
"""The tests for the Home Assistant API component.""" """The tests for the Home Assistant API component."""
import asyncio
from http import HTTPStatus from http import HTTPStatus
import json import json
from unittest.mock import patch from unittest.mock import patch
from aiohttp import web from aiohttp import ServerDisconnectedError, web
from aiohttp.test_utils import TestClient from aiohttp.test_utils import TestClient
import pytest import pytest
import voluptuous as vol import voluptuous as vol
@ -352,26 +353,41 @@ async def test_api_call_service_with_data(
assert state["attributes"] == {"data": 1} assert state["attributes"] == {"data": 1}
async def test_api_call_service_timeout( async def test_api_call_service_client_closed(
hass: HomeAssistant, mock_api_client: TestClient hass: HomeAssistant, mock_api_client: TestClient
) -> None: ) -> None:
"""Test if the API does not fail on long running services.""" """Test that services keep running if client is closed."""
test_value = [] test_value = []
fut = hass.loop.create_future() fut = hass.loop.create_future()
service_call_started = asyncio.Event()
async def listener(service_call): async def listener(service_call):
"""Wait and return after mock_api_client.post finishes.""" """Wait and return after mock_api_client.post finishes."""
service_call_started.set()
value = await fut value = await fut
test_value.append(value) test_value.append(value)
hass.services.async_register("test_domain", "test_service", listener) hass.services.async_register("test_domain", "test_service", listener)
with patch("homeassistant.components.api.SERVICE_WAIT_TIMEOUT", 0): api_task = hass.async_create_task(
await mock_api_client.post("/api/services/test_domain/test_service") mock_api_client.post("/api/services/test_domain/test_service")
assert len(test_value) == 0 )
fut.set_result(1)
await hass.async_block_till_done() await service_call_started.wait()
assert len(test_value) == 0
await mock_api_client.close()
assert len(test_value) == 0
assert api_task.done()
with pytest.raises(ServerDisconnectedError):
await api_task
fut.set_result(1)
await hass.async_block_till_done()
assert len(test_value) == 1 assert len(test_value) == 1
assert test_value[0] == 1 assert test_value[0] == 1