Checking whether an async* dispatcher is "alive"

Magnus Lie Hetland mlh at vier.idi.ntnu.no
Sun Apr 14 09:26:22 EDT 2002


In article <Oj5u8.34280$%A.2510727 at news1.west.cox.net>, Van Gale wrote:
[snip]
>Hmm, this is a bit tricky and depends some on how your protocol works.

Oh... I was mainly after a way of checking whether I could write to
the socket or not. It seems that exceptions are generated if is has
been closed (fine by me) but that the asyncore dispatcher intercepts
these and just prints a log message. I could override the error
handling methods to pass through the exception (so I could handle it
myself) -- I just though there might be another way.

[snip]
>I presume however, that your protocol is asynchronous over a persistent
>connection since you are implying you want to send data to a client without
>having just recieved a request.

Yes. I have a list of connected clients and would like to remove the
dead ones.

> In this case you really only have 2
>choices: either just trust TCP's built-in reliability, tr-try, and
>keep-alive features or you can implement some kind of heartbeat message.

I don't mind trusting TCP, if that means that I'll get an exception
when trying to send something to a dead (as determined by TCP) socket.
It just seems that I then have to override the exception handling of
asynchat.async_chat. I had just hoped that there would be some
ready-made way of checking this.

>See pg 581 of [1] for a discussion and sample C code for using TCP's ugent
>mode to implement heartbeats.  His implementation has the client send the
>heartbeats and the server raises a signal if it hasn't recieved any
>heartbeats after a specified interval.  I don't know how portable this is,
>or even how easy it would be to implement in Python if you're using async*
>classes.

Yes, this does sound like a very safe way of doing things, but kind of
overkill in my case, I think. (Possible extension, sure...)

>My personal preference (atm) is just trusting TCP and handling errors when
>the connection is broken because you're going to get a send error on the
>heartbeat anyway :)

Yes, that sounds just fine -- but how do I do that?

I've tried something like:

  alive = []
  for session in self.sessions:
      try:
          session.push(message)
          alive.append(session)
      except socket.error: pass
  self.sessions = alive

but since the push() simply logs the error, this doesn't work. If I
override handle_error, I could probably make this work (or?). But are
there other ways of doing it? Something in the API that I've missed
(like Thread.isAlive)?

>If you're implementing something like a server for an
>IM protocol (e.g. Jabber) which needs up to date "presence" information,
>then it should have a heartbeat built-in to the protocol (as does Jabber).

I don't really need that. Actually, I could live with having a bunch
of dead sessions too, I guess. But somehow, it seems that the default
exception handling wreaks havoc somehow (making it difficult to
re-connect or something -- not exactly sure what happens).

>Btw, the Medusa http_server, status_handler, and the monitor_server, are
>probably worth checking out even if your protocol is fully asynchronous.  I
>really like having a port I can connect to with a browser that gives me a
>nice picture of the internal status of the running server, and
>monitor_server takes the ultimate step: it gives you an interactive Python
>session inside your running server.

Yeah, that is cool :)

>Van
>[1] W. Richard Stevens "Unix Network Programming: Networking APIs: Sockets
>and XTI Volume 1"
>

--
Magnus Lie Hetland                                  The Anygui Project
http://hetland.org                                  http://anygui.org



More information about the Python-list mailing list