HTTPX PoolTimeout no es un tiempo de espera de conexión al proxy
Identifica la espera del pool de HTTPX y libera las respuestas en streaming antes de sustituir un proxy que quizá ni recibió la siguiente petición.
PoolTimeout significa que HTTPX no pudo obtener una conexión de su pool dentro del tiempo de espera configurado. No demuestra que una nueva conexión TCP al proxy agotara su tiempo. La segunda petición puede seguir esperando dentro de tu proceso.
Es fácil reproducirlo cuando el cliente permite una sola conexión y la primera respuesta en streaming se queda abierta. Iniciar otra petición no libera esa conexión por arte de magia.
Deja claro quién se encarga de la respuesta en streaming
import httpx
limits = httpx.Limits(
max_connections=1,
max_keepalive_connections=1,
)
timeout = httpx.Timeout(
connect=5, read=10, write=10, pool=1
)
with httpx.Client(
proxy="http://203.0.113.10:8080",
trust_env=False,
limits=limits,
timeout=timeout,
) as client:
with client.stream("GET", "https://example.com/") as response:
print(response.status_code)
for chunk in response.iter_bytes():
print(len(chunk))
next_response = client.get("https://example.com/")
print(next_response.status_code)
Sustituye la dirección de proxy de documentación antes de ejecutarlo. La siguiente petición empieza después de salir del contexto del stream. Esa salida cierra la respuesta aunque el código abandone el bucle o lance una excepción.
Con streaming manual, como client.send(request, stream=True), tu código es responsable del cierre final. Para AsyncClient, la limpieza manual correspondiente se espera con response.aclose(). Cerrar una respuesta sin leer libera capacidad, pero puede exigir descartar la conexión subyacente en lugar de reutilizarla.
Lee el nombre de la excepción
ConnectTimeout se refiere a establecer la conexión. ReadTimeout se refiere a esperar datos de respuesta. PoolTimeout se refiere a obtener una plaza de conexión. Registrar solo «timeout del proxy» pierde la distinción necesaria para elegir una solución.
Revisa respuestas abiertas, tareas concurrentes y límites de conexión antes de cambiar las IP de los puntos de conexión. Un pool mayor puede ser adecuado para una carga concurrente legítima, pero no corrige respuestas que nunca se cierran. Solo da a la aplicación más capacidad que ocupar.
Conserva el cliente para reutilizarlo durante la carga de trabajo. Reconstruirlo para que cada petición parezca funcionar puede ocultar un problema de ciclo de vida y descartar la reutilización de conexiones.