PoolTimeout หมายถึง HTTPX ดึงการเชื่อมต่อจากพูลไม่ได้ภายในเวลารอที่ตั้งไว้ ไม่ใช่หลักฐานว่าการเชื่อมต่อ TCP ใหม่ไปพร็อกซีหมดเวลา คำขอที่สองอาจยังรออยู่ภายในโปรเซสของคุณ

ทำให้เกิดซ้ำได้ง่ายเมื่อไคลเอนต์อนุญาตเพียงหนึ่งการเชื่อมต่อและคำตอบสตรีมแรกถูกเปิดค้างไว้ การเริ่มคำขอใหม่ไม่ได้คืนการเชื่อมต่อนั้นเอง

ทำให้ชัดว่าใครรับผิดชอบคำตอบสตรีม

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)

แทนที่ที่อยู่พร็อกซีตัวอย่างในเอกสารก่อนรัน คำขอถัดไปเริ่มหลังออกจากบริบทของสตรีม การออกนั้นปิดคำตอบแม้โค้ดหยุดลูปหรือเกิดข้อยกเว้น

เมื่อสตรีมแบบจัดการเอง เช่น client.send(request, stream=True) โค้ดของคุณรับผิดชอบการปิดในท้ายที่สุด สำหรับ AsyncClient ต้องรอการเก็บกวาดเองที่สอดคล้องกันด้วย response.aclose() การปิดคำตอบที่ยังไม่ได้อ่านคืนความจุ แต่บางครั้งต้องทิ้งการเชื่อมต่อด้านล่างแทนนำกลับมาใช้ซ้ำ

อ่านชื่อข้อยกเว้น

ConnectTimeout เกี่ยวกับการสร้างการเชื่อมต่อ ReadTimeout เกี่ยวกับการรอข้อมูลคำตอบ PoolTimeout เกี่ยวกับการได้ช่องการเชื่อมต่อ การบันทึกแค่ «พร็อกซีหมดเวลา» ทำให้เสียความต่างที่ใช้เลือกวิธีแก้

ตรวจคำตอบที่เปิดอยู่ งานพร้อมกัน และขีดจำกัดการเชื่อมต่อก่อนเปลี่ยน IP จุดเชื่อมต่อ พูลที่ใหญ่ขึ้นอาจเหมาะกับภาระงานพร้อมกันที่สมเหตุสมผล แต่ไม่แก้คำตอบที่ไม่เคยปิด เพียงให้แอปมีความจุมากขึ้นให้ครอบครอง

เก็บไคลเอนต์ไว้ใช้ซ้ำตลอดภาระงาน การสร้างไคลเอนต์ใหม่เพื่อให้แต่ละคำขอดูเหมือนทำงานได้อาจซ่อนปัญหาวงจรชีวิต และเสียการนำการเชื่อมต่อกลับมาใช้ซ้ำ

บทความที่เกี่ยวข้อง