PoolTimeout înseamnă că HTTPX nu a obținut o conexiune din pool în timpul de așteptare configurat. Nu dovedește că o nouă conexiune TCP cu proxy-ul a expirat. A doua cerere poate încă aștepta în procesul tău.

Situația se reproduce ușor când clientul permite o conexiune, iar primul răspuns în streaming rămâne deschis. Pornirea altei cereri nu eliberează acea conexiune prin magie.

Fă vizibilă responsabilitatea pentru răspunsul în 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)

Înlocuiește adresa proxy de documentație înainte de rulare. Următoarea cerere începe după ieșirea din contextul streamului. Ieșirea închide răspunsul chiar dacă programul întrerupe bucla sau ridică o excepție.

La streaming manual, precum client.send(request, stream=True), codul tău răspunde de închiderea finală. Pentru AsyncClient, curățarea manuală corespunzătoare este așteptată cu response.aclose(). Închiderea unui răspuns necitit eliberează capacitate, dar poate cere abandonarea conexiunii subiacente în locul reutilizării.

Citește numele excepției

ConnectTimeout privește stabilirea conexiunii. ReadTimeout privește așteptarea datelor de răspuns. PoolTimeout privește obținerea unui loc de conexiune. Jurnalizarea doar a unui «timeout proxy» pierde distincția necesară alegerii unei remedieri.

Verifică răspunsurile deschise, sarcinile concurente și limitele de conexiune înainte să schimbi IP-urile endpointurilor. Un pool mai mare poate fi potrivit pentru o încărcare concurentă legitimă, dar nu repară răspunsurile niciodată închise. Doar oferă aplicației mai multă capacitate de ocupat.

Păstrează clientul reutilizabil pe durata încărcării. Reconstruirea lui pentru a face fiecare cerere să pară funcțională poate ascunde o problemă de ciclu de viață și pierde reutilizarea conexiunilor.

Articole similare