with timeout(...):

Hendrik van Rooyen mail at microcorp.co.za
Tue Mar 27 02:47:26 EDT 2007


 "Diez B. Roggisch" <deets at nospam.web.de> wrote:


> Nick Craig-Wood wrote:
> 
> > Did anyone write a contextmanager implementing a timeout for
> > python2.5?
> > 
> > I'd love to be able to write something like
> > 
> >     with timeout(5.0) as exceeded:
> >         some_long_running_stuff()
> >     if exceeded:
> >         print "Oops - took too long!"
> > 
> > And have it work reliably and in a cross platform way!
> 
> Cross platform isn't the issue here - reliability though is. To put it
> simple: can't be done that way. You could of course add a timer to the
> python bytecode core, that would "jump back" to a stored savepoint or
> something like that.
> 
> But to make that work reliably, it has to be ensured that no sideeffects
> occur while being in some_long_running_stuff. which doesn't only extend to
> python itself, but also external modules and systems (file writing, network
> communications...). Which can't be done, unless you use a time-machine.
> Which I'd take as an personal insult, because in that rolled-back timeframe
> I will be possibly proposing to my future wife or something...
> 

how does the timed callback in the Tkinter stuff work - in my experience so 
far it seems that it does the timed callback quite reliably...

probably has to do with the fact that the mainloop runs as a stand alone 
process, and that you set the timer up when you do the "after" call.

so it probably means that to emulate that kind of thing you need a 
separate "thread" that is in a loop to monitor the timer's expiry, that 
somehow gains control from the "long running stuff" periodically...

so Diez is probably right that the way to go is to put the timer in the
python interpreter loop, as its the only thing around that you could 
more or less trust to run all the time.

But then it will not read as nice as Nick's wish, but more like this:

id = setup_callback(error_routine, timeout_in_milliseconds)
long_running_stuff_that_can_block_on_IO(foo, bar, baz)
cancel_callback(id)
print "Hooray it worked !! "
sys.exit()

def error_routine():
    print "toughies it took too long - your chocolate is toast"
    attempt_at_recovery_or_explanation(foo, bar, baz)

Much more ugly.
But would be useful to be able to do without messing with
threads and GUI and imports. 
Could be hard to implement as the interpreter would have 
to be assured of getting control back periodically, so a 
ticker interrupt routine is called for - begins to sound more 
like a kernel function to me.  
Isn't there something available that could be got at via ctypes?

- Hendrik







More information about the Python-list mailing list