Best strategy for overcoming excessive gethostbyname timeout.

MRAB python at mrabarnett.plus.com
Fri Nov 27 22:58:13 EST 2009


r0g wrote:
> Hi,
> 
> I'm writing a reliability monitoring app but I've run into a problem. I
> was hoping to keep it very simple and single threaded at first but
> that's looking unlikely now! The crux of it is this...
> 
> gethostbyname ignores setdefaulttimeout.
> 
> It seems gethostbyname asks the OS to resolve the address and the OS
> uses it's own timeout value ( 25 seconds ) rather than the one provided
> in setdefaulttimeout. 25 seconds of blocking is way too long for me, I
> want the response within 5 seconds or not at all but I can see no
> reasonable way to do this without messing with the OS which naturally I
> am loathe to do!
> 
> The two ideas I've had so far are...
> 
> Implement a cache. For this to work I'd need to avoid issuing
> gethostbyname until the cached address fails. Of course it will fail a
> little bit further down i the calling code when the app tries to use it
> and I'd then need it to refresh the cache and try again. That seems very
> kludgey to me :/
> 
> A pure python DNS lookup. This seems better but is an unknown quantity.
> How big a job is it to use non-blocking sockets to write a DNS lookup
> function with a customisable timeout? A few lines? A few hundred? I'd
> only need to  resolve v4 addresses for the foreseeable.
> 
> Any comments on these strategies, or any suggestions of methods you
> think might work better or be a lot easier to implement, warmly received.
> 
How about something like this:

def get_host_by_name(hostname, timeout):
     def proc():
         try:
             q.put(socket.gethostbyname(hostname))
         except (socket.gaierror, socket.timeout):
             pass

     q = Queue.Queue()
     t = threading.Thread(target=proc)
     t.daemon = True
     t.start()
     try:
         return q.get(True, timeout)
     except Queue.Empty:
         raise socket.timeout



More information about the Python-list mailing list