I have written a simple TimeManager
: a context manager that fires of a threading.Timer
when the context is entered and cancels it when it is exited. If the timer goes off before exiting the context, it raises an exception:
import threading
class TimeManager(object):
def __init__(self):
self._timeout = 1
def _timeoutHandler(self):
raise Exception("Timeout!")
def __enter__(self):
self.timer = threading.Timer(self._timeout, self._timeoutHandler)
self.timer.start()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.timer.cancel()
return False
Obviously I can't catch the exception in the main thread, as it belongs to a separate thread:
>>> with TimeManager() as t:
... try:
... time.sleep(5)
... except Exception:
... print "caught"
...
Exception in thread Thread-3:
Traceback (most recent call last):
File "/usr/lib64/python2.6/threading.py", line 532, in __bootstrap_inner
self.run()
File "/usr/lib64/python2.6/threading.py", line 736, in run
self.function(*self.args, **self.kwargs)
File "<stdin>", line 5, in _timeoutHandler
Exception: Timeout!
So, how can I catch the exception in the main thread? Should I abandon the idea of the context manager?
Notice the problem is different from the one described here, there are no multiple threads involved there. I think it is also different from this, where message passing would negate the purpose of the timeout.