On 22 Ott, 12:28, Giampaolo Rodola' <[EMAIL PROTECTED]> wrote: > Hi there. > We're talking about an asyncore-based server. > Just for the heck of it I'd like to set a timeout which will > disconnects the clients if they're inactive (i.e., no command or data > transfer in progress) for a long period of time. > I was thinking about putting the timeout value into an attribute: > > def settimeout(self, secs): > self.timeout = time.time() + secs > > And then have the readable method call time.time() at every loop to > check if time has passed or not: > > def readable(self): > if time.time() >= self.timeout: > self.send("Timeout") > self.close() > return 1 > > My only concern is if it's a good idea calling time.time() so often. > Since A LOT of clients could be connected simultaneously, couldn't it > be a too much resource-intensive operation? > I'd also be curious to know how Twisted implemented this kind of > stuff. > By calling time.time() at every loop? > > Thanks in advance.
Calling time.time() is relatively inexpensive in comparison to pure Python function calls, but indeed, it could be a bottleneck. I don't know what Twisted does, but what I would do is to add two variables to each instance of the class you want to add timeouts to; self.timeout and self.lastdata . self.lastdata would hold the time for the last time you sent or received data on the socket, and self.timeout would hold the delay between when you last sent/received data and when it should be closed due to idle timeout. Now, since you are smart, you don't need to alter your handle_send() or handle_receive() methods in your asyncore subclass. Instead, you rewrite asyncore.poll() to update .lastdata for every socket that is in either the reader or writer list, which will result in one time.time() call. Further, to check for timeouts, you only ever need to check those sockets that are *not* in the readable or writable lists... To be precise, add the following block to your own copy of asyncore.poll just after the 'for fd in e:' block... #handle timeouts rw = set(r) + set(w) now = time.time() for f in (i for i in rw if i in map): map[f].lastdata = now for j in (map[i] for i in map if i not in rw): if j.timeout+j.lastdata > now: #timeout! j.handle_close() You ARE going to need to initialize .timeout and .lastdata members for every instance, but that shouldn't be so bad (for a socket that doesn't time out, I would actually suggest a 1 hour or 1 day timeout). - Josiah -- http://mail.python.org/mailman/listinfo/python-list