asyncore: suggested patch

Jonathan Feinberg jdf at pobox.com
Sat May 26 09:28:28 EDT 2001


I wrote the following note to Sam Rushing some weeks back, and never
heard back from him, so I thought I'd go ahead and post it here.

--------------------------------

First of all, thanks so much for your excellent asyncore and related
modules.

I am implementing a "link checker", a program that takes a list of
URLs and returns a hash whose keys are the URLs and whose values are
the server status codes for those URLs, or error messages as
appropriate (such as 'host not found').

In the case that a host's address is bad, there was no problem;
connect() would raise a socket.error with 'host not found'.  But in
the case where the host is okay, but the *port* is wrong (i.e.,
http://www.foo.com:666/), I would poll endlessly.  I found that I
could solve the problem by overriding the connect() method in my
subclass of async_chat, such that it takes an optional timeout
argument, as follows:

    def connect(self, address, timeout = 0):
        self.connected = 0
        try:
            self.socket.connect (address)
        except socket.error, why:
            if why[0] in (EWOULDBLOCK, EINPROGRESS) and timeout > 0:
                r,w,e = select.select([],[self.socket],[],timeout)
                if not w: raise socket.error('host not reachable')
            elif why[0] in (EWOULDBLOCK, EINPROGRESS, EALREADY):
                return
            else:
                raise socket.error, why
        self.connected = 1
        self.handle_connect()

I found that in the case where the host is legitimate, but there is
nothing listening on the specified port, Windows 2000 raises
EWOULDBLOCK, while NetBSD raises EINPROGRESS, which is why I check for
both.

I like this solution, as it doesn't break any existing code, and
solves my problem.  I don't like it, because I'm afraid that the use
of a timeout has implications that are beyond my ken.  At any rate, I
present it to you with the thought that you may find it useful enough
to incorporate into asyncore.

If you don't think it belongs in asyncore, I'll simply post this in
c.l.py, and let people ignore it as they please. :)

-- 
Jonathan Feinberg   jdf at pobox.com   Sunny Brooklyn, NY
http://pobox.com/~jdf



More information about the Python-list mailing list