A better way to timeout a class method?
John O'Hagan
research at johnohagan.com
Tue Mar 10 02:37:21 EDT 2009
On Mon, 9 Mar 2009, Nick Craig-Wood wrote:
> John O'Hagan <research at johnohagan.com> wrote:
> > Is there a concise Pythonic way to write a method with a timeout?
> >
> > I did this:
> >
> > class Eg(object):
> >
> > def get_value(self, timeout):
> >
> > from threading import Timer
> > self.flag = True
> >
> > def flag_off():
> > self.flag = False
> > timer = Timer(timeout, flag_off)
> > timer.start()
> >
> > while self.flag:
> > #do stuff for a long time to get some value
> > if condition: #if we ever get the value
> > self.value = value
> > break
> >
> > but it seems hackish to have a special "flag" attribute just to manage
> > the timeout within the the method.
>
> How about something like this
>
> from threading import Timer
>
> class Duration(object):
> def __init__(self, duration):
> self.running = True
> self.timer = Timer(duration, self.set_finished)
> self.timer.setDaemon(True)
> self.timer.start()
> def set_finished(self):
> self.running = False
> def __nonzero__(self):
> return self.running
Nifty! Works for threads too because they can have access to the Duration
object. I guess it works on a similar principle to my attempt (setting a flag
with a timer) but is cleaner by keeping everything inside the method.
So my original method would look like this:
class ExIt(object):
def __init__(self, iter_func, args=None):
self.iter_func = iter_func
self.args = args
self.length = None
def get_length(self, timeout=None):
"""Try to get length of iterator
within a time limit"""
if self.length is None:
from threading import Thread, Timer
timer=Duration(timeout)
def count():
gen = self.iter_func(self.args)
length = 0
while timer:
try:
gen.next()
length += 1
except StopIteration:
self.length = length
break
getlen = Thread(target=count)
getlen.setDaemon(True)
getlen.start()
Which does exactly what I want: runs a time-consuming task in the background
and can optionally time it out. In fact that's so handy, I think it would be
nice if there was a standard timer object which is True while running, then
False. Or maybe there is?
Thanks,
John
More information about the Python-list
mailing list