python.sync_dns_lookup
Performance
Medium
Detects socket.gethostbyname() or socket.getaddrinfo() in async functions.
Why It Matters
Section titled “Why It Matters”DNS lookups are blocking operations:
- Hidden latency — DNS resolution can take hundreds of milliseconds
- Event loop blocked — No other tasks can run during the lookup
- Resolver failures — If DNS resolvers are slow, everything stalls
- No timeout control — System DNS has its own timeout, often too long
In async code, blocking DNS destroys the concurrency benefits you’re trying to achieve.
Example
Section titled “Example”# ❌ Beforeasync def resolve_host(hostname): return socket.gethostbyname(hostname)This blocks the event loop for the entire DNS resolution.
# ✅ Afterasync def resolve_host(hostname): loop = asyncio.get_event_loop() return await loop.getaddrinfo(hostname, None)getaddrinfo is async-aware and doesn’t block.
What Unfault Detects
Section titled “What Unfault Detects”socket.gethostbyname()in async functionssocket.gethostbyname_ex()in async functionssocket.getaddrinfo()(without await) in async functionssocket.gethostbyaddr()in async functions
Auto-Fix
Section titled “Auto-Fix”Unfault replaces blocking socket calls with async equivalents.
Best Practices
Section titled “Best Practices”# Use asyncio's built-in resolverloop = asyncio.get_event_loop()result = await loop.getaddrinfo(host, port)
# Or use aiohttp which handles this internallyasync with aiohttp.ClientSession() as session: async with session.get(url) as response: ... # DNS is async
# For complex DNS needs, use aiodnsimport aiodnsresolver = aiodns.DNSResolver()result = await resolver.query(hostname, 'A')