socket setdefaulttimeout

Bryan Olson fakeaddress at nowhere.org
Sat Aug 13 02:35:54 EDT 2005


Sheila King wrote:
 > Bryan Olson wrote:
[...]
 >>Under some older threading systems, any system call would block every
 >>thread in the process, and gethostbyname was notorious for holding things
 >>up.  Some systems offer an asynchronous gethostbyname, but that doesn't
 >>help users of Python's library. Some programmers would keep around a few
 >>extra processes to handle their hosts lookups.  Fortunately, threading
 >>systems are now much better, and should only block the thread waiting for
 >>gethostbyname.
 >
 >
 > Thanks, Bryan. I'm not doing any threading. But we are running this 
script on
 > incoming email as it arrives at the SMTP server, and scripts have a 
16 second
 > max time of execution. Generally they run in much less time. However, 
we have
 > seen incidents where, due to issues with the DNS servers for the 
blacklists,
 > that the script exceed it's max time to run and the process was 
killed by
 > the OS. This results in the email being placed back into the mail 
queue for
 > attempted re-delivery later. Of course, if this issue goes 
undetected, the
 > mail can eventually be "returned to sender". There's no effective way 
to check
 > from within the running filter script that the time is not exceeded 
if the
 > gethostbyname blocks and doesn't return. :(
 >
 > As I said, normally this isn't a problem. But there have been a 
handful of
 > incidents where it did cause issues briefly over a few days. I was 
hoping to
 > address it. :/
 >
 > Sounds like I'm out of luck.

The seperate thread-or-process trick should work. Start a deamon
thread to do the gethostbyname, and have the main thread give up
on the check if the deamon thread doesn't report (via a lock or
another socket) within, say, 8 seconds.

If you have decent thread support, you might do it like as
follows. (Oviously didn't have time test this well.)



     from threading import Thread
     from Queue import Queue, Empty
     import socket


     def start_deamon_thread(func):
         """ Run func -- a callable of zero args -- in a deamon thread.
         """
         thread = Thread(target = func)
         thread.setDaemon(True)
         thread.start()

     def gethostbyname_or_timeout(hostname, timeout_secs = 8):
         """ Return IP address from gethostbyname, or None on timeout.
         """
         queue = Queue(1)

         def attempt_ghbn():
             queue.put(socket.gethostbyname(hostname))

         start_deamon_thread(attempt_ghbn)
         try:
             result = queue.get(block = True, timeout = timeout_secs)
         except Empty:
             result = None
         return result


-- 
--Bryan



More information about the Python-list mailing list