Explanation
Your problem is that you don't override method asyncore.dispatcher.writeable
, default implementation:
def writable(self):
return True
Which causes asyncore.poll
to run in while True
loop (thus using 100% CPU):
def poll(timeout=0.0, map=None):
if map is None:
map = socket_map
if map:
r = []; w = []; e = []
for fd, obj in map.items():
is_r = obj.readable()
is_w = obj.writable() # This is always true
if is_r:
r.append(fd)
if is_w:
w.append(fd)
if is_r or is_w:
e.append(fd) # This always happens
if [] == r == w == e:
time.sleep(timeout) # This never happens
return
try:
# Here, having w (as function parameter) set to non-empty value
# causes select to immediately return without waiting with w set
# just to your client
r, w, e = select.select(r, w, e, timeout)
Solution
I think really clean solution would be re-implementing asyncore with some sort of threading.Event
mechanism that would enforce waiting for writable object, but so far this worked for me:
# Add to RemoteClient
def writable(self):
''' It has point to call handle_write only when there's something in outbox
Having this method always returning true will cause 100% CPU usage
'''
return bool(self.outbox)
# When you start loop
asyncore.loop(timeout=5.0)
You also can see writable()
overridden in example in official documentation.
I just prefer to be able to kill waiting sooner than after 30 seconds.