HTTPX PoolTimeout não é timeout de conexão com o proxy
Identifique a espera no pool do HTTPX e libere respostas em streaming antes de trocar um proxy que talvez nem tenha recebido outra requisição.
PoolTimeout significa que o HTTPX não conseguiu obter uma conexão do pool dentro do tempo de espera configurado. Isso não prova que uma nova conexão TCP com o proxy excedeu o prazo. A segunda requisição pode ainda estar esperando dentro do seu processo.
Isso fica fácil de reproduzir quando o cliente permite uma conexão e a primeira resposta em streaming é deixada aberta. Iniciar outra requisição não libera essa conexão por mágica.
Deixe clara a responsabilidade pela resposta em 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)
Troque o endereço de proxy de documentação antes de executar. A próxima requisição começa depois que o contexto do stream termina. Essa saída fecha a resposta mesmo que o código interrompa o laço ou lance uma exceção.
No streaming manual, como client.send(request, stream=True), seu código é responsável pelo fechamento final. No AsyncClient, a limpeza manual correspondente é aguardada com response.aclose(). Fechar uma resposta não lida libera capacidade, mas pode exigir descartar a conexão subjacente em vez de reutilizá-la.
Leia o nome da exceção
ConnectTimeout trata do estabelecimento da conexão. ReadTimeout trata da espera por dados da resposta. PoolTimeout trata de obter uma vaga de conexão. Registrar apenas «timeout do proxy» perde a distinção necessária para escolher a correção.
Verifique respostas abertas, tarefas concorrentes e limites de conexão antes de trocar IPs dos endpoints. Um pool maior pode ser adequado para uma carga concorrente legítima, mas não corrige respostas que nunca são fechadas. Só oferece mais capacidade para a aplicação ocupar.
Mantenha o cliente reutilizável durante a carga de trabalho. Reconstruí-lo para fazer cada requisição parecer funcionar pode esconder um problema de ciclo de vida e perder a reutilização de conexões.