# Copyright (c) 2012-2015 Denis Bilenko. See LICENSE for details."""Native thread-based hostname resolver."""import_socketfromgevent.hubimportget_hub__all__=['Resolver']
[docs]classResolver(object):""" Implementation of the resolver API using native threads and native resolution functions. Using the native resolution mechanisms ensures the highest compatibility with what a non-gevent program would return including good support for platform specific configuration mechanisms. The use of native (non-greenlet) threads ensures that a caller doesn't block other greenlets. This implementation also has the benefit of being very simple in comparison to :class:`gevent.resolver_ares.Resolver`. .. tip:: Most users find this resolver to be quite reliable in a properly monkey-patched environment. However, there have been some reports of long delays, slow performance or even hangs, particularly in long-lived programs that make many, many DNS requests. If you suspect that may be happening to you, try the dnspython or ares resolver (and submit a bug report). """def__init__(self,hub=None):ifhubisNone:hub=get_hub()self.pool=hub.threadpoolif_socket.gaierrornotinhub.NOT_ERROR:# Do not cause lookup failures to get printed by the default# error handler. This can be very noisy.hub.NOT_ERROR+=(_socket.gaierror,_socket.herror)def__repr__(self):return'<%s.%s at 0x%x pool=%r>'%(type(self).__module__,type(self).__name__,id(self),self.pool)defclose(self):pass# from briefly reading socketmodule.c, it seems that all of the functions# below are thread-safe in Python, even if they are not thread-safe in C.defgethostbyname(self,*args):returnself.pool.apply(_socket.gethostbyname,args)defgethostbyname_ex(self,*args):returnself.pool.apply(_socket.gethostbyname_ex,args)defgetaddrinfo(self,*args,**kwargs):returnself.pool.apply(_socket.getaddrinfo,args,kwargs)defgethostbyaddr(self,*args,**kwargs):returnself.pool.apply(_socket.gethostbyaddr,args,kwargs)defgetnameinfo(self,*args,**kwargs):returnself.pool.apply(_socket.getnameinfo,args,kwargs)