forked from openshift/openshift-tools
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimeout.py
More file actions
77 lines (59 loc) · 2.38 KB
/
timeout.py
File metadata and controls
77 lines (59 loc) · 2.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# vim: expandtab:tabstop=4:shiftwidth=4
''' The purpose of this module is to give a decorator and anonymous block
statement that can be used to timeout a function or block of code if
it runs for too long.
Example Usage:
from openshift_tools.timeout import timeout, timed
@timed(20)
def some_function():
# do something that should always finish within 20 seconds
def some_function():
with timeout(seconds=20):
# do something that should always finish within 20 seconds
'''
import signal
from functools import wraps
class TimeoutException(Exception):
''' For raising timeouts '''
pass
def timed(seconds):
''' Use as a decorator to timeout a function after so many seconds '''
def outer(decorated_function):
''' Outer function of the decorator '''
@wraps(decorated_function)
def wrapper(*args, **kwargs):
''' Wraps the decorated function, where the magic happens '''
with timeout(seconds=seconds):
result = decorated_function(*args, **kwargs)
return result
return wrapper
return outer
# Reason: disable pylint invalid-name
# pylint does not like the name 'timeout'
# Status: permanently disabled
# pylint: disable=invalid-name
class timeout(object):
''' anonymous block for setting arbritrary timeouts '''
# Reason: disable pylint too-few-public-methods
# Status: permanently disabled
# pylint: disable=too-few-public-methods
def __init__(self, seconds, error_message='Timeout'):
self.seconds = seconds
self.error_message = error_message
self.old_handler = None
def handle_timeout(self, signum, frame):
''' called in the event of a timeout. just raise an exception '''
del signum #make pylint happy
del frame #make pylint happy
raise TimeoutException(self.error_message)
def __enter__(self):
self.old_handler = signal.signal(signal.SIGALRM, self.handle_timeout)
signal.alarm(self.seconds)
# Reason: disable pylint redefined-builtin
# Status: permanently disabled
# pylint: disable=redefined-builtin
def __exit__(self, type, value, traceback):
# Reset the alarm
signal.alarm(0)
# make sure the original handler is now back in place
signal.signal(signal.SIGALRM, self.old_handler)