Re: A better way to timeout a class method?
On Mon, 9 Mar 2009, Nick Craig-Wood wrote: John O'Hagan resea...@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 -- http://mail.python.org/mailman/listinfo/python-list
A better way to timeout a class method?
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. Any comments appreciated. Regards, John P.S. A more detailed but non-essential example: The use case is an iterator class which has a method to get the length of an instance, and does this as a thread so that other operations can proceed. It is subject to a timeout as the iterator may be arbitrarily long. Showing just the relevant method: 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: self.flag = True from threading import Thread def count(): gen = self.iter_func(self.args) length = 0 while self.flag: try: gen.next() length += 1 except StopIteration: self.length = length break getlen = Thread(target=count) getlen.setDaemon(True) if timeout: from threading import Timer def flag_off(): self.flag = False timer = Timer(timeout, flag_off) timer.start() getlen.start() Any comments on this also appreciated. -- http://mail.python.org/mailman/listinfo/python-list
Re: A better way to timeout a class method?
John O'Hagan wrote: Is there a concise Pythonic way to write a method with a timeout? No need for threading. Just define a signal handler and call signal.alarm(). See the example at the end of the page: http://docs.python.org/library/signal.html -- http://mail.python.org/mailman/listinfo/python-list
Re: A better way to timeout a class method?
Marco Mariani ma...@sferacarta.com wrote: John O'Hagan wrote: Is there a concise Pythonic way to write a method with a timeout? No need for threading. Just define a signal handler and call signal.alarm(). See the example at the end of the page: http://docs.python.org/library/signal.html Won't work on windows and there is only one sigalarm timer, so you can't nest them :-( -- Nick Craig-Wood n...@craig-wood.com -- http://www.craig-wood.com/nick -- http://mail.python.org/mailman/listinfo/python-list
Re: A better way to timeout a class method?
John O'Hagan resea...@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 from time import sleep def long_function(): duration = Duration(5) i = 0 print starting while duration: print i i += 1 sleep(1) print finished long_function() Which prints starting 0 1 2 3 4 finished -- Nick Craig-Wood n...@craig-wood.com -- http://www.craig-wood.com/nick -- http://mail.python.org/mailman/listinfo/python-list
Re: A better way to timeout a class method?
On Mon, 9 Mar 2009, Marco Mariani wrote: John O'Hagan wrote: Is there a concise Pythonic way to write a method with a timeout? No need for threading. Just define a signal handler and call signal.alarm(). Thanks, that works well in general; but unfortunately the method in question (see the P.S. in my original post) starts a thread, and it's the thread that needs to timeout; unfortunately signal doesn't work in a thread. So I guess I need to rephrase my question as: how to timeout a thread? Regards, John -- http://mail.python.org/mailman/listinfo/python-list