Re: A better way to timeout a class method?

2009-03-10 Thread John O'Hagan
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?

2009-03-09 Thread 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.
--
http://mail.python.org/mailman/listinfo/python-list


Re: A better way to timeout a class method?

2009-03-09 Thread Marco Mariani

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?

2009-03-09 Thread Nick Craig-Wood
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?

2009-03-09 Thread Nick Craig-Wood
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?

2009-03-09 Thread John O'Hagan
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