Forum: Ruby limiting how long a method is permiited to run

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Brian B. (Guest)
on 2005-12-05 18:57
(Received via mailing list)
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.
bob_showalter (Guest)
on 2005-12-05 19:02
(Received via mailing list)
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/
decoux (Guest)
on 2005-12-05 19:06
(Received via mailing list)
>>>>> "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
leavengood (Guest)
on 2005-12-05 20:07
(Received via mailing list)
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
pfharlock (Guest)
on 2005-12-05 20:12
(Received via mailing list)
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"
Brian B. (Guest)
on 2005-12-05 20:24
(Received via mailing list)
> 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
This topic is locked and can not be replied to.