Describe the feature you want to add
The lock-based adapters (Issue #15) guarantee thread safety but serialize all DNS resolution. In high-concurrency applications this creates a bottleneck, threads wait on each other even though they could resolve DNS independently.
We need a fully concurrent approach that allows multiple threads to perform filtered DNS resolution simultaneously without blocking each other.
Describe your proposed solution
Introduce IPv4ThreadLocalAdapter and IPv6ThreadLocalAdapter that use a threading.local() dispatch pattern:
On first use, the original socket.getaddrinfo is replaced once with a dispatcher function
The dispatcher checks a per-thread threading.local() variable for the desired address family filter
Each adapter's send() sets the thread-local filter before calling super().send() and clears it afterward in a try/finally block
Threads without a filter set get unfiltered (original) behavior.
Key properties:
- Fully concurrent: no lock held during HTTP requests
- Thread-isolated: one thread's IPv4 filter cannot affect another thread's resolution
- One-time global patch:
socket.getaddrinfo is replaced lazily on first adapter use (double-checked locking for thread-safe installation)
- Compatible with Python 3.7+
Describe alternatives you've considered, if relevant
No response
Additional context
No response
Describe the feature you want to add
The lock-based adapters (Issue #15) guarantee thread safety but serialize all DNS resolution. In high-concurrency applications this creates a bottleneck, threads wait on each other even though they could resolve DNS independently.
We need a fully concurrent approach that allows multiple threads to perform filtered DNS resolution simultaneously without blocking each other.
Describe your proposed solution
Introduce
IPv4ThreadLocalAdapterandIPv6ThreadLocalAdapterthat use athreading.local()dispatch pattern:On first use, the original
socket.getaddrinfois replaced once with a dispatcher functionThe dispatcher checks a per-thread
threading.local()variable for the desired address family filterEach adapter's
send()sets the thread-local filter before callingsuper().send()and clears it afterward in a try/finally blockThreads without a filter set get unfiltered (original) behavior.
Key properties:
socket.getaddrinfois replaced lazily on first adapter use (double-checked locking for thread-safe installation)Describe alternatives you've considered, if relevant
No response
Additional context
No response