Skip to content

Commit 5eb3638

Browse files
committed
optimize usage
1 parent 3a60889 commit 5eb3638

File tree

4 files changed

+32
-24
lines changed

4 files changed

+32
-24
lines changed

README.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,19 @@ Timeout Timer
1010
it support loop nesting, if use signal timer, outside timer will fired after the inside
1111
signal timer finish the work(raise exception or normal finish).
1212

13-
Signal timer can only work on main thread, if not on main thread use thread timer, thread timer may cost
13+
Support signal timer and thread timer, signal timer can only work on main thread, if not on main thread use thread timer, thread timer may cost
1414
longer time than time out seconds settled if the timer's sub thread(user's function) is busy in a
1515
system call (time.sleep(), socket.accept()...), exception will fired after system call done.
1616

1717
Usage
1818
============
1919
support nested loop
2020
::
21+
from timeout_timer import timeout, TimeoutInterrupt
2122
try:
22-
with TimeoutTimer(2, timer="signal") as f:
23+
with timeout(2, timer="signal") as f:
2324
f(time.sleep, 0.5)
24-
with TimeoutTimer(1, timer="signal") as f2:
25+
with timeout(1, timer="signal") as f2:
2526
f2(time.sleep, 2)
2627
except TimeoutInterrupt:
2728
print("timeout triggered")
@@ -30,14 +31,14 @@ support nested loop
3031
or use signal timer can simplify
3132
::
3233
try:
33-
with TimeoutTimer(2) :
34+
with timeout(2) :
3435
time.sleep(3)
3536
except TimeoutInterrupt:
3637
print("timeout triggered")
3738

3839
or use as decorator
3940
::
40-
@TimeoutTimer(2):
41+
@timeout(2):
4142
def f():
4243
time.sleep(3)
4344
time.sleep(2)

tests/timeout_timer_test.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# coding: utf-8
2-
from timeout_timer.timeout_timer import TimeoutTimer, TimeoutInterrupt
2+
from timeout_timer import timeout, TimeoutInterrupt
33
import time
44

55
import pytest
@@ -22,7 +22,7 @@ def sleep(s):
2222
def test_timeout_no_seconds(timer):
2323
is_timeout = None
2424
try:
25-
with TimeoutTimer(0, timer=timer) as f:
25+
with timeout(0, timer=timer) as f:
2626
f(sleep, 1)
2727
except TimeoutInterrupt:
2828
is_timeout = True
@@ -32,7 +32,7 @@ def test_timeout_no_seconds(timer):
3232
def test_timeout_seconds(timer):
3333
is_timeout = None
3434
try:
35-
with TimeoutTimer(1, timer=timer) as f:
35+
with timeout(1, timer=timer) as f:
3636
f(sleep, 2)
3737
except TimeoutInterrupt:
3838
is_timeout = True
@@ -43,12 +43,12 @@ def test_timeout_nested_loop_inside_timeout(timer):
4343
try:
4444
def s():
4545
try:
46-
with TimeoutTimer(2, timer=timer, exception=TimeoutInterruptNested) as f2:
46+
with timeout(2, timer=timer, exception=TimeoutInterruptNested) as f2:
4747
f2(sleep, 3)
4848
except TimeoutInterruptNested:
4949
return True
5050

51-
with TimeoutTimer(10, timer=timer) as f:
51+
with timeout(10, timer=timer) as f:
5252
is_timeout = f(s)
5353

5454
except TimeoutInterrupt:
@@ -60,12 +60,12 @@ def test_timeout_nested_loop_outsite_timeout(timer):
6060
try:
6161
def s():
6262
try:
63-
with TimeoutTimer(10, timer=timer, exception=TimeoutInterruptNested) as f2:
63+
with timeout(10, timer=timer, exception=TimeoutInterruptNested) as f2:
6464
f2(sleep, 3)
6565
except TimeoutInterruptNested:
6666
return True
6767

68-
with TimeoutTimer(2, timer=timer) as f:
68+
with timeout(2, timer=timer) as f:
6969
is_timeout = f(s)
7070

7171
except TimeoutInterrupt:
@@ -78,14 +78,14 @@ def test_timeout_nested_loop_both_timeout(timer):
7878
try:
7979
def s():
8080
try:
81-
with TimeoutTimer(2, timer=timer, exception=TimeoutInterruptNested) as f2:
81+
with timeout(2, timer=timer, exception=TimeoutInterruptNested) as f2:
8282
f2(sleep, 2)
8383
except TimeoutInterruptNested:
8484
cnt.append(1)
8585
time.sleep(10)
8686
cnt.append(0)
8787

88-
with TimeoutTimer(5, timer=timer) as f:
88+
with timeout(5, timer=timer) as f:
8989
f(s)
9090
except TimeoutInterrupt:
9191
cnt.append(1)

timeout_timer/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
# coding: utf-8
2+
from .timeout_timer import timeout, TimeoutInterrupt, TimeoutTimer, StoppableThread
3+
4+
__all__ = ['timeout', 'TimeoutInterrupt']
25
__version__ = "0.1.0"

timeout_timer/timeout_timer.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
class TimeoutInterrupt(BaseException):
1111
"""inherit from baseException in cased captured by board Exception(eg: except Exception) in user program"""
1212

13-
def __init__(self, value=""):
14-
self.value = str(value)
13+
def __init__(self):
14+
self.value = "Timeout Interrupt"
1515

1616
def __str__(self):
1717
return self.value
@@ -58,7 +58,7 @@ def __new__(cls, *args, **kwargs):
5858

5959
raise NotImplementedError
6060

61-
def __init__(self, seconds, timer="signal", exception=TimeoutInterrupt, message="", interval=1):
61+
def __init__(self, seconds, timer="signal", exception=TimeoutInterrupt, interval=1):
6262
"""
6363
:param seconds: seconds to raise a timeout exception if user func
6464
:param timer: the timeout timer to use signal or threading, "signal" or "thread"
@@ -68,7 +68,6 @@ def __init__(self, seconds, timer="signal", exception=TimeoutInterrupt, message=
6868
"""
6969
self.timeout_seconds = seconds
7070
self.exception_class = exception
71-
self.exception_message = message
7271
self.timer = timer
7372
self.interval = interval
7473

@@ -136,7 +135,7 @@ def cancel(self):
136135

137136
def timeout_callback(self, signum, frame):
138137
"""signal callback"""
139-
raise self.exception_class(self.exception_message or str(frame))
138+
raise self.exception_class()
140139

141140

142141
class _ThreadTimeoutTimer(TimeoutTimer):
@@ -150,20 +149,22 @@ def __init__(self, *args, **kwargs):
150149
super(_ThreadTimeoutTimer, self).__init__(*args, **kwargs)
151150

152151
def _exec_func(self, func, *args, **kwargs):
153-
_out_time = time.time() + self.timeout_seconds
154152
tt = _TimerThread(self.exception_class)
155153
tt.set_func(partial(func, *args, **kwargs))
156154
tt.setDaemon(True)
157155
tt.start()
156+
157+
_out_time = time.time() + self.timeout_seconds
158158
stop_fired = False
159159
# wait for task done, it stop may delayed when thread is busy in
160160
# a system call (time.sleep(), socket.accept(), ...)
161161
while not tt.func_done:
162-
if (not stop_fired) and _out_time <= time.time():
162+
if not stop_fired and _out_time <= time.time():
163163
stop_fired = True
164164
tt.stop()
165165
else:
166-
time.sleep(self.interval)
166+
remain_time = _out_time - time.time()
167+
time.sleep(self.interval if remain_time > self.interval else remain_time if remain_time > 0 else 0.1)
167168

168169
if tt.error:
169170
raise tt.error
@@ -309,6 +310,9 @@ def set_func(self, func):
309310
def stop(self, exception=None):
310311
super(_TimerThread, self).stop(exception or self.exception_class)
311312

313+
314+
timeout = TimeoutTimer
315+
312316
if __name__ == "__main__":
313317
def f():
314318
while True:
@@ -319,7 +323,7 @@ def f():
319323
# cost 5s
320324
t = time.time()
321325
try:
322-
with TimeoutTimer(5) as ff:
326+
with timeout(5) as ff:
323327
ff(f)
324328
except TimeoutInterrupt as e:
325329
print(e)
@@ -329,7 +333,7 @@ def f():
329333
# cost 10s
330334
try:
331335
t = time.time()
332-
with TimeoutTimer(5, timer="thread") as ff:
336+
with timeout(5, timer="thread") as ff:
333337
ff(f)
334338
except TimeoutInterrupt as e:
335339
print(e)

0 commit comments

Comments
 (0)