2

Lets say I have a tcl script which should normally execute in less than a minute - How could I make sure that the script NEVER takes more than 'x' minutes/seconds to execute, and if it does then the script should just be stopped.

For example, if the script has taken more than 100 seconds, then I should be able to automatically switch control to a clean up function which would gracefully end the script so that I have all the data from the script run so far but I also ensure that it doesn't take too long or get stuck infinitely.

I'm not sure if this can be done in tcl - any help or pointers would be welcome.

egorulz
  • 1,455
  • 2
  • 17
  • 28

2 Answers2

4

You could use interp limit when you use a child interpreter.

Note that this will throw an uncachable error, if you want to do some cleanup you to remove the limit in a parent interp.

set interp [interp create]
# initialize the interp
interp eval $interp {
     source somestuff.tcl
}
# Add the limit. From now you have 60 seconds or an error will be thrown
interp limit $interp time -seconds [clock seconds] -milliseconds 60000
set errorcode [catch {interp eval {DoExpensiveStuff}} res opts]
# remove the limit so you can cleanup the mess if needed.
interp limit $interp time -seconds {}
if {$errorcode} {
    # Do some cleanup here
}
# delete the interp, or reuse it?
interp delete $interp
# And what shall be done with the error? Throw it.
return -options $opt $res

Resource limits are the best bet with Tcl, but they are not bullet-proof. Tcl can not (and will not) abort C procedures, and there are some ways to let the Tcl core do some hard working.

Johannes Kuhn
  • 14,778
  • 4
  • 49
  • 73
0

There must be a loop that you're worried might take more than 100 seconds, yes? Save clock seconds (current time) before you enter the loop, and check the time again at the end of each iteration to see if more than 100 seconds have elapsed.

If for some reason that's not possible, you can try devising something using after—that is, kick off a timer to a callback that sets (or unsets) some global variable that your executing code is aware of—so that on detection, it can attempt to exit.

Andrew Cheong
  • 29,362
  • 15
  • 90
  • 145
  • Actually it's not a loop - rather a list of commands which need to be run. Each command might take a few seconds, but in some cases one of them might get stuck causing the script to be stuck forever. – egorulz Nov 14 '13 at 09:51