Describe the feature you want to add
The current IPv4TransportAdapter and IPv6TransportAdapter are not thread-safe. They temporarily replace the global socket.getaddrinfo function during each send() call without any synchronization. In multi-threaded applications (for example using ThreadPoolExecutor or threaded web servers), concurrent requests can race to patch/restore getaddrinfo, leading to corrupted DNS resolution, leaked patches, or incorrect address family filtering.
We need a thread-safe adapter variant that guarantees correctness under concurrent access. The simplest and most universally compatible approach is a process-wide threading.Lock that serializes access to the socket.getaddrinfo patch. This ensures that only one thread at a time can modify and read the global function, eliminating all race conditions.
Describe your proposed solution
Introduce IPv4LockAdapter and IPv6LockAdapter classes that extend HTTPAdapter. They share a module-level threading.Lock. Before patching socket.getaddrinfo, the adapter acquires the lock; after the underlying send() completes (or raises), the lock is released and getaddrinfo is restored.
Key design choices:
- Single shared lock across all lock-based adapter instances (both IPv4 and IPv6)
- Compatible with Python 3.7+ (no new stdlib dependencies beyond threading)
- Trade-off: DNS resolution is serialized across threads (throughput limited)
Describe alternatives you've considered, if relevant
No response
Additional context
No response
Describe the feature you want to add
The current
IPv4TransportAdapterandIPv6TransportAdapterare not thread-safe. They temporarily replace the globalsocket.getaddrinfofunction during eachsend()call without any synchronization. In multi-threaded applications (for example usingThreadPoolExecutoror threaded web servers), concurrent requests can race to patch/restoregetaddrinfo, leading to corrupted DNS resolution, leaked patches, or incorrect address family filtering.We need a thread-safe adapter variant that guarantees correctness under concurrent access. The simplest and most universally compatible approach is a process-wide
threading.Lockthat serializes access to thesocket.getaddrinfopatch. This ensures that only one thread at a time can modify and read the global function, eliminating all race conditions.Describe your proposed solution
Introduce
IPv4LockAdapterandIPv6LockAdapterclasses that extendHTTPAdapter. They share a module-levelthreading.Lock. Before patchingsocket.getaddrinfo, the adapter acquires the lock; after the underlyingsend()completes (or raises), the lock is released andgetaddrinfois restored.Key design choices:
Describe alternatives you've considered, if relevant
No response
Additional context
No response