HTTPX PoolTimeout ist kein Verbindungs-Timeout zum Proxy
Erkennen Sie das Warten auf den HTTPX-Verbindungspool und geben Sie Streaming-Antworten frei, bevor Sie einen Proxy ersetzen, der womöglich keine weitere Anfrage erhielt.
PoolTimeout bedeutet, dass HTTPX innerhalb der eingestellten Wartezeit keine Verbindung aus dem Pool erhalten konnte. Es beweist kein Timeout einer neuen TCP-Verbindung zum Proxy. Die zweite Anfrage wartet möglicherweise noch in Ihrem Prozess.
Das lässt sich leicht reproduzieren, wenn der Client nur eine Verbindung zulässt und die erste Streaming-Antwort offen bleibt. Eine weitere Anfrage zu starten bedeutet nicht, dass diese Verbindung von selbst frei wird.
Die Verantwortung für Streaming-Antworten sichtbar halten
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)
Ersetzen Sie vor der Ausführung die Dokumentationsadresse des Proxys. Die nächste Anfrage beginnt erst nach dem Verlassen des Stream-Kontexts. Dabei wird die Antwort auch dann geschlossen, wenn der Code die Schleife abbricht oder eine Ausnahme auslöst.
Bei manuellem Streaming, etwa client.send(request, stream=True), ist Ihr Code für das spätere Schließen zuständig. Bei AsyncClient wird die entsprechende manuelle Bereinigung mit response.aclose() abgewartet. Das Schließen einer ungelesenen Antwort gibt Kapazität frei, kann aber das Verwerfen der zugrunde liegenden Verbindung statt ihrer Wiederverwendung erfordern.
Den Namen der Ausnahme lesen
ConnectTimeout betrifft den Verbindungsaufbau. ReadTimeout betrifft das Warten auf Antwortdaten. PoolTimeout betrifft das Erlangen eines Verbindungsplatzes. Wer nur „Proxy-Timeout“ protokolliert, verliert die für eine passende Lösung nötige Unterscheidung.
Prüfen Sie offene Antworten, gleichzeitige Aufgaben und Verbindungslimits, bevor Sie Endpunkt-IPs tauschen. Ein größerer Pool kann für berechtigte parallele Last sinnvoll sein, korrigiert aber keine Antworten, die nie geschlossen werden. Er gibt der Anwendung lediglich mehr Kapazität zum Belegen.
Verwenden Sie den Client über die gesamte Arbeitslast wieder. Für jede Anfrage einen neuen Client zu bauen, damit sie scheinbar funktioniert, kann ein Lebenszyklusproblem verdecken und die Verbindungswiederverwendung aufgeben.