J
John O'Hagan
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.
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.