Reputation: 44325
I am following some example code to use asyncore
here, only having set a timeout
value for asyncore.loop
as in the following full example:
import smtpd
import asyncore
class CustomSMTPServer(smtpd.SMTPServer):
def process_message(self, peer, mailfrom, rcpttos, data):
print 'Receiving message from:', peer
print 'Message addressed from:', mailfrom
print 'Message addressed to :', rcpttos
print 'Message length :', len(data)
return
server = CustomSMTPServer(('127.0.0.1', 1025), None)
asyncore.loop(timeout = 1)
I have expected that a timeout occurs after 1 second, but this is not the case. The code runs much longer for than one second. What am I missing here?
Upvotes: 0
Views: 4529
Reputation: 10539
The timeout of asyncore.loop() is the timeout for select().
It is not useful, because when select() timeout, it loops back, see the pseudo code:
while True:
do_something()
select(...)
do_something_else()
If I do simulation with firewall-ed sockets, in my Python 2.7.3 asyncore.loop() timeout 1 minute after no data is received from some socket.
I found very useful to have following method in asyncore.dispatcher "subclass":
def handle_error(self):
raise
In this way I had "proper" exception dump.
Because I do not wanted to have exception, later I changed it to something like:
def handle_error(self):
print "Error downloading %s" % self.host
pass
Now my code works correct, without exception.
I did not found a way to control the timeout.
Upvotes: 0
Reputation: 44325
I really do not know if the timeout
argument to asyncore.loop()
really is meant to timeout the function call asyncore.loop()
after the specified time, but here is a receipt to make that function timeout after a specified time (replacing the line with asyncore.loop()
in the example code):
import signal
class TimeoutError(Exception): pass
# define the timeout handler
def handler(signum, frame):
raise TimeoutError()
# set the timeout handler and the signal duration
signal.signal(signal.SIGALRM, handler)
signal.alarm(1)
try:
asyncore.loop()
except TimeoutError as exc:
print "timeout"
finally:
signal.alarm(0)
Upvotes: 1
Reputation: 3520
The timeout
argument to asyncore.loop()
is the amount of time the select.select
call will wait for data. If there is no data before the timeout
runs out it will loop and call select.select
again.
Same for the channels
idea. This does not mean open sockets but means active asyncore.dispatcher
or asynchat.async_chat
instances. If you want to stop the loop you will have to call the close()
method on ALL instances registered.
In your case server.close()
will close the instance/channel and remove it from the asyncore
loop. If no more channels are active this loop will then terminate itself.
Upvotes: 2