Limiting how long a method is permiited to run


#1

Hello all,

Is there a means of limiting how long a method is permiited to run? I
want to be able to mark a method with a number and have the method
throw, say, a TooMuchTimeException if the running time exceeds this
number.

I am envisioning declaratively applying such limits, either in the
class definition or setting the limits on individual objects.

Example: class Foo has instance methods calc1, cal2, etc. Depending
on the state of the foo object and the parameters passed into the
methods, these methods might run in a fraction of the second or they
might take minutes.

class Foo
def calc1
#complex work …
end

def calc2(a, b)
#more complex work …
end

#declare maximum time limit like this…
#TooMuchTimeException exception to be thrown if method takes too long
time_limit :calc1=>5, :calc2=>20
end

Is there anything already written that does this type of thing?

Thanks.

–Brian B.


#2

Brian B. wrote:

Hello all,

Is there a means of limiting how long a method is permiited to run? I
want to be able to mark a method with a number and have the method
throw, say, a TooMuchTimeException if the running time exceeds this
number.

http://www.ruby-doc.org/stdlib/libdoc/timeout/rdoc/


#3

“B” == Brian B. removed_email_address@domain.invalid writes:

B> Is there a means of limiting how long a method is permiited to run?
I
B> want to be able to mark a method with a number and have the method
B> throw, say, a TooMuchTimeException if the running time exceeds this
B> number.

Well, you have timeout.rb in the standard distribution

= timeout.rb

execution timeout

= Synopsis

require ‘timeout’

status = Timeout::timeout(5) {

# Something that should be interrupted if it takes too much

time…

}

= Description

A way of performing a potentially long-running operation in a thread,

and terminating

it’s execution if it hasn’t finished by a fixed amount of time.

Previous versions of timeout didn’t provide use a module for

namespace. This version

provides both Timeout.timeout, and a backwards-compatible #timeout.

Guy Decoux


#4

On 12/5/05, Brian B. removed_email_address@domain.invalid wrote:

Is there anything already written that does this type of thing?

Try this out Brian:

require ‘timeout’

class TooMuchTimeException < Exception;end

class Class
def time_limit(hash)
hash.each do |name, limit|
m = instance_method(name)
define_method(name) do
timeout(limit, TooMuchTimeException) do
m.bind(self).call
end
end
end
end
end

class Foo
def calc1
1
end

def calc2
sleep(7)
2
end

time_limit :calc1 => 20, :calc2 => 5
end

f = Foo.new
p f.calc1
p f.calc2


#5

On windows, without having to go to the level of processes or using
fork, (as it doesn’t work on windows), is there a way to timeout either
a call to system or a call using the backtic sytax as in the following
logical code which doesn’t work?

require ‘timeout’

begin
status = Timeout::timeout(1) do
notepad
while(true)
puts “this is to fill up the rest of the time”
end
end
rescue Timeout::Error
puts “Here is the code from rescue”
end

puts “And here is code after the begin/end block”


#6

Try this out Brian:

Sweet! I added in *args and it seems to do exactly what I was looking
for.

class Class
def time_limit(hash)
hash.each do |name, limit|
m = instance_method(name)
define_method(name) do |*args|
timeout(limit, TooMuchTimeException) do
m.bind(self).call(*args)
end
end
end
end
end