Search code examples
pythontimeoutgevent

How come the gevent timeout exception is never caught by my except clause?


The code never reaches the print 'never reach1' or print 'never reach2' line when I try to telnet into the server.

import sys, signal
from gevent.server import StreamServer
from gevent.pool import Pool
from gevent import monkey
import gevent
from gevent import Timeout
import random

class SocketPool(object):

    def __init__(self):
        self.pool = Pool(1000)

    def listen(self, socket):
        while True:
            line = socket.recv(1024)
            print line

    def add_handler(self, socket, address):
        if self.pool.full():
            raise Exception("At maximum pool size")
        else:
            self.pool.spawn(self.listen, socket)
            gevent.spawn(self.wait).join()

    def wait(self):
        try:
            timeout = Timeout(1)
            timeout.start()
        except Timeout:
            print 'never reach1'
        except:
            print 'never reach2'

    def shutdown(self): self.pool.kill()

def signal_handler(signal, frame): sys.exit(0)

signal.signal(signal.SIGINT, signal_handler)
monkey.patch_all()
sockPool = SocketPool()
server = StreamServer(('127.0.0.1', 5000), sockPool.add_handler)
server.serve_forever()

Solution

  • As you can see from the documentation:

    timeout = Timeout(seconds, exception)
    timeout.start()
    try:
        ...  # exception will be raised here, after *seconds* passed since start() call
    finally:
        timeout.cancel()
    

    So your try block is completely executed and hence cannot catch the exception. You should put something like a while loop or a computation that requires at least 1 second to see the exception.

    If you want to make a method that simply "sleeps" without using CPU I'd recommend using a simple time.sleep instead of using a Timeout.