Created
February 22, 2012 20:09
-
-
Save nvie/1886939 to your computer and use it in GitHub Desktop.
Example of a time-guarded context
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import signal | |
class JobTimeoutException(Exception): | |
pass | |
class death_pentalty_after(object): | |
def __init__(self, timeout): | |
self._timeout = timeout | |
def __enter__(self): | |
self.setup_death_penalty() | |
def __exit__(self, type, value, traceback): | |
# Always cancel immediately, since we're done | |
try: | |
self.cancel_death_penalty() | |
except JobTimeoutException: | |
# Weird case: we're done with the with body, but now the alarm is | |
# fired. We may safely ignore this situation and consider the | |
# body done. | |
pass | |
# __exit__ may return True to supress further exception handling. We | |
# don't want to suppress any exceptions here, since all errors should | |
# just pass through, JobTimeoutException being handled normally to the | |
# invoking context. | |
return False | |
def handle_death_penalty(self, signum, frame): | |
raise JobTimeoutException('Job exceeded maximum timeout ' | |
'value (%d seconds).' % self._timeout) | |
def setup_death_penalty(self): | |
"""Sets up an alarm signal and a signal handler that raises | |
a JobTimeoutException after the timeout amount (expressed in | |
seconds). | |
""" | |
signal.signal(signal.SIGALRM, self.handle_death_penalty) | |
signal.alarm(self._timeout) | |
def cancel_death_penalty(self): | |
"""Removes the death penalty alarm and puts back the system into | |
default signal handling. | |
""" | |
signal.alarm(0) | |
signal.signal(signal.SIGALRM, signal.SIG_DFL) | |
if __name__ == '__main__': | |
def slow_fib(n): | |
if n <= 1: | |
return 1 | |
return slow_fib(n - 2) + slow_fib(n - 1) | |
try: | |
with death_pentalty_after(8): | |
for i in range(0, 50): | |
print i, '=>', slow_fib(i) | |
except JobTimeoutException: | |
print('Buy a faster machine to calculate more fibonacci numbers :)') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment