From 7d0e1731d915a54cf94265470585c3f16adbd3d0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 3 Jul 2023 10:41:15 -0500 Subject: [PATCH 1/3] Tune keep alives for polling integrations aiohttp closes the connection after 15s by default, and httpx closes the connection after 5s by default. We have a lot of integrations that poll every 10-60s which create and tear down connections over and over. Set the keep alive time to 65s to maximize connection reuse and avoid tls negotiation overhead --- homeassistant/helpers/aiohttp_client.py | 6 ++++++ homeassistant/helpers/httpx_client.py | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 8208c774887010..53e17002d9d6b8 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -59,6 +59,11 @@ MAXIMUM_CONNECTIONS = 4096 MAXIMUM_CONNECTIONS_PER_HOST = 100 +# We have a lot of integrations that poll every 60 seconds +# and we want to keep the connection open for a while so we +# don't have to reconnect every time. +KEEP_ALIVE_TIMEOUT = 65 + class HassClientResponse(aiohttp.ClientResponse): """aiohttp.ClientResponse with a json method that uses json_loads by default.""" @@ -284,6 +289,7 @@ def _async_get_connector( connector = aiohttp.TCPConnector( enable_cleanup_closed=ENABLE_CLEANUP_CLOSED, ssl=ssl_context, + keepalive_timeout=KEEP_ALIVE_TIMEOUT, limit=MAXIMUM_CONNECTIONS, limit_per_host=MAXIMUM_CONNECTIONS_PER_HOST, ) diff --git a/homeassistant/helpers/httpx_client.py b/homeassistant/helpers/httpx_client.py index beb084d8c1c63f..5304b044314932 100644 --- a/homeassistant/helpers/httpx_client.py +++ b/homeassistant/helpers/httpx_client.py @@ -19,8 +19,13 @@ from .frame import warn_use +# We have a lot of integrations that poll every 60 seconds +# and we want to keep the connection open for a while so we +# don't have to reconnect every time. +KEEP_ALIVE_TIMEOUT = 65 DATA_ASYNC_CLIENT = "httpx_async_client" DATA_ASYNC_CLIENT_NOVERIFY = "httpx_async_client_noverify" +DEFAULT_LIMITS = limits = httpx.Limits(keepalive_expiry=KEEP_ALIVE_TIMEOUT) SERVER_SOFTWARE = "{0}/{1} httpx/{2} Python/{3[0]}.{3[1]}".format( APPLICATION_NAME, __version__, httpx.__version__, sys.version_info ) @@ -78,6 +83,7 @@ def create_async_httpx_client( client = HassHttpXAsyncClient( verify=ssl_context, headers={USER_AGENT: SERVER_SOFTWARE}, + limits=DEFAULT_LIMITS, **kwargs, ) From 686ed6d02f50503b706097028b50e45ed712263b Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 3 Jul 2023 11:15:27 -0500 Subject: [PATCH 2/3] Apply suggestions from code review --- homeassistant/helpers/aiohttp_client.py | 4 ++-- homeassistant/helpers/httpx_client.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 53e17002d9d6b8..81dc7b02d40fe4 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -59,10 +59,10 @@ MAXIMUM_CONNECTIONS = 4096 MAXIMUM_CONNECTIONS_PER_HOST = 100 -# We have a lot of integrations that poll every 60 seconds +# We have a lot of integrations that poll every 10-30 seconds # and we want to keep the connection open for a while so we # don't have to reconnect every time. -KEEP_ALIVE_TIMEOUT = 65 +KEEP_ALIVE_TIMEOUT = 32 class HassClientResponse(aiohttp.ClientResponse): diff --git a/homeassistant/helpers/httpx_client.py b/homeassistant/helpers/httpx_client.py index 5304b044314932..6661bde98ac30b 100644 --- a/homeassistant/helpers/httpx_client.py +++ b/homeassistant/helpers/httpx_client.py @@ -19,10 +19,10 @@ from .frame import warn_use -# We have a lot of integrations that poll every 60 seconds +# We have a lot of integrations that poll every 10-30 seconds # and we want to keep the connection open for a while so we # don't have to reconnect every time. -KEEP_ALIVE_TIMEOUT = 65 +KEEP_ALIVE_TIMEOUT = 32 DATA_ASYNC_CLIENT = "httpx_async_client" DATA_ASYNC_CLIENT_NOVERIFY = "httpx_async_client_noverify" DEFAULT_LIMITS = limits = httpx.Limits(keepalive_expiry=KEEP_ALIVE_TIMEOUT) From 66c92f538f10bb12ac3c53a6d67f5270bca2a928 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 3 Jul 2023 11:29:23 -0500 Subject: [PATCH 3/3] adjust --- homeassistant/helpers/aiohttp_client.py | 6 ------ homeassistant/helpers/httpx_client.py | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/homeassistant/helpers/aiohttp_client.py b/homeassistant/helpers/aiohttp_client.py index 81dc7b02d40fe4..8208c774887010 100644 --- a/homeassistant/helpers/aiohttp_client.py +++ b/homeassistant/helpers/aiohttp_client.py @@ -59,11 +59,6 @@ MAXIMUM_CONNECTIONS = 4096 MAXIMUM_CONNECTIONS_PER_HOST = 100 -# We have a lot of integrations that poll every 10-30 seconds -# and we want to keep the connection open for a while so we -# don't have to reconnect every time. -KEEP_ALIVE_TIMEOUT = 32 - class HassClientResponse(aiohttp.ClientResponse): """aiohttp.ClientResponse with a json method that uses json_loads by default.""" @@ -289,7 +284,6 @@ def _async_get_connector( connector = aiohttp.TCPConnector( enable_cleanup_closed=ENABLE_CLEANUP_CLOSED, ssl=ssl_context, - keepalive_timeout=KEEP_ALIVE_TIMEOUT, limit=MAXIMUM_CONNECTIONS, limit_per_host=MAXIMUM_CONNECTIONS_PER_HOST, ) diff --git a/homeassistant/helpers/httpx_client.py b/homeassistant/helpers/httpx_client.py index 6661bde98ac30b..93b199b1db56cf 100644 --- a/homeassistant/helpers/httpx_client.py +++ b/homeassistant/helpers/httpx_client.py @@ -21,8 +21,8 @@ # We have a lot of integrations that poll every 10-30 seconds # and we want to keep the connection open for a while so we -# don't have to reconnect every time. -KEEP_ALIVE_TIMEOUT = 32 +# don't have to reconnect every time so we use 15s to match aiohttp. +KEEP_ALIVE_TIMEOUT = 15 DATA_ASYNC_CLIENT = "httpx_async_client" DATA_ASYNC_CLIENT_NOVERIFY = "httpx_async_client_noverify" DEFAULT_LIMITS = limits = httpx.Limits(keepalive_expiry=KEEP_ALIVE_TIMEOUT)