Ruby has a nice exception handling recovery construct in its 'retry'; using python I needed the same for my ping spewer CookingPacketsWithDugsong as depending on system load, contention would occur and some syscalls would not immediately work.

I solved this by using the following semi-functional code:

def retry(*args, **kwargs): if kwargs.has_key('count') == False: kwargs['count'] = 5 if kwargs.has_key('seconds') == False: kwargs['seconds'] = 1 for attempt in xrange( kwargs['count'] ): try: if len(args) > 1: ret = args[0](args[1:]) else: ret = args[0]() except: time.sleep( random.random() * kwargs['seconds'] ) else: return ret raise OSError, sys.exc_info()[1]

I used it in my updated packet spewer as:

def init(): sock = socket.socket( socket.AF_INET, socket.SOCK_RAW, socket.getprotobyname('icmp') ) sock.settimeout(2) return sock def start(): sock.sendto( str(icmp), (ip, 1) ) return time.time() def end(): sock.recvfrom(0x100) return time.time() try: sock = retry( init ) clock_start = retry( start ) clock_end = retry( end ) except OSError, e: return (ip, e.args) else: return (ip, clock_end - clock_start)

A better way probably exists, since init(), start(), and end() could probably at least have parameters. Even worse, I had to set up a tuple return value that indicates failure, so one can't ever return a tuple with None as first value.

I'll switch retry() to raise an error when it finally gives up, and stick the returned sys.exc_info() into that. I need to read further on function calls; first I have to run to my Chinese meetup out here in Seattle....

Switching retry() to use exceptions makes a lot more sense. Now for the function argument passing... and thanks to simple variable argument support, that wraps it up quite nicely.