Limiting how long a method is permiited to run

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 Buckley

Brian Buckley 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/

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.

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

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

···

On 12/5/05, Brian Buckley <briankbuckley@gmail.com> wrote:

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

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"

ts wrote:

···

"B" == Brian Buckley <briankbuckley@gmail.com> writes:

> 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.

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

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