From eb3612ac5d860ef21af99a83ce978b2fba30d6d4 Mon Sep 17 00:00:00 2001 From: hingebase Date: Sun, 19 Oct 2025 14:41:44 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Resolve=20DNS=20with?= =?UTF-8?q?=20`cyares`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 1 + src/mahoraga/_asgi/_server.py | 5 +++- src/mahoraga/_core/_context.py | 53 +++++++++++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 5a10fb9..2afb562 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -31,6 +31,7 @@ classifiers = [ dependencies = [ "aiohttp >=3.13.0", "anyio >=4.10.0", + "cyares[aiohttp,idna] >=0.1.4", "fastapi >=0.118.3", "filelock >=3.20.0", "hishel >=0.1.4", diff --git a/src/mahoraga/_asgi/_server.py b/src/mahoraga/_asgi/_server.py index 15742e8..9f6a419 100644 --- a/src/mahoraga/_asgi/_server.py +++ b/src/mahoraga/_asgi/_server.py @@ -127,7 +127,10 @@ async def _main( headers={"User-Agent": f"mahoraga/{__version__}"}, timeout=httpx.Timeout(15, read=60, write=60), follow_redirects=False, - limits=httpx.Limits(keepalive_expiry=cfg.server.keep_alive), + limits=httpx.Limits( + max_connections=cfg.server.limit_concurrency, + keepalive_expiry=cfg.server.keep_alive, + ), event_hooks=event_hooks, storage=hishel.AsyncInMemoryStorage(capacity=1024), controller=hishel.Controller( diff --git a/src/mahoraga/_core/_context.py b/src/mahoraga/_core/_context.py index 0e5203d..124ce51 100644 --- a/src/mahoraga/_core/_context.py +++ b/src/mahoraga/_core/_context.py @@ -30,11 +30,14 @@ import weakref from typing import TYPE_CHECKING, Any, TypedDict, overload, override +import aiohttp import anyio +import cyares.aiohttp import hishel import httpx import httpx_aiohttp import pydantic_settings +from httpx._config import DEFAULT_LIMITS # noqa: PLC2701 from rattler.networking.fetch_repo_data import CacheAction from mahoraga import _core @@ -42,11 +45,37 @@ if TYPE_CHECKING: from collections.abc import AsyncGenerator, Awaitable from concurrent.futures import ProcessPoolExecutor + from ssl import SSLContext from _typeshed import StrPath + from httpx._types import CertTypes -class AsyncClient(hishel.AsyncCacheClient, httpx_aiohttp.HttpxAiohttpClient): +class _HttpxAiohttpClient(httpx.AsyncClient): + @override + def _init_transport( + self, + verify: SSLContext | str | bool = True, + cert: CertTypes | None = None, + trust_env: bool = True, + http1: bool = True, + http2: bool = False, + limits: httpx.Limits = DEFAULT_LIMITS, + transport: httpx.AsyncBaseTransport | None = None, + ) -> httpx.AsyncBaseTransport: + if transport is not None: + return transport + return _AiohttpTransport( + verify=verify, + cert=cert, + trust_env=trust_env, + http1=http1, + http2=http2, + limits=limits, + ) + + +class AsyncClient(hishel.AsyncCacheClient, _HttpxAiohttpClient): @override def _transport_for_url(self, url: httpx.URL) -> httpx.AsyncBaseTransport: t = super()._transport_for_url(url) @@ -179,6 +208,28 @@ async def _cached_or_locked(cache_location: StrPath) -> AsyncGenerator[bool]: yield True +class _AiohttpTransport(httpx_aiohttp.AiohttpTransport): + @override + def get_client(self) -> aiohttp.ClientSession: + if ( + callable(self.client) + or isinstance(self.client, aiohttp.ClientSession) + or self.uds + or not self.limits.max_connections + ): + return super().get_client() + connector = aiohttp.TCPConnector( + limit=self.limits.max_connections, + keepalive_timeout=self.limits.keepalive_expiry, + ssl=self.ssl_context, + local_addr=(self.local_address, 0) if self.local_address else None, + resolver=cyares.aiohttp.CyAresResolver( + loop=asyncio.get_running_loop(), + ), + ) + return aiohttp.ClientSession(connector=connector) + + class _Context(TypedDict): config: _core.Config httpx_client: AsyncClient From 87b47426f7556c6cc5d4ab6ae8d5262349cd7814 Mon Sep 17 00:00:00 2001 From: hingebase Date: Sat, 24 Jan 2026 20:49:23 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20cyares=200.4.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 00508bb..9adf164 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,8 +30,7 @@ classifiers = [ ] dependencies = [ "aiohttp >=3.13.0", - "anyio >=4.10.0", - "cyares[aiohttp,idna] >=0.1.4", + "cyares[aiohttp,anyio,idna] >=0.4.0", "distributed >=2026.1.1", "filelock >=3.20.0", "hishel[fastapi,httpx,requests] >=1.1.5",