In Files

  • timeout.rb

Namespace

Methods

Class/Module Index [+]

Quicksearch

Timeout

Description

A way of performing a potentially long-running operation in a thread, and terminating it's execution if it hasn't finished within fixed amount of time.

Previous versions of timeout didn't use a module for namespace. This version provides both ::timeout, and a backwards-compatible timeout.

Synopsis

require 'timeout'
status = Timeout::timeout(5) {
  # Something that should be interrupted if it takes too much time...
}

Public Class Methods

timeout(sec, klass = nil) click to toggle source

Executes the method's block. If the block execution terminates before sec seconds has passed, it returns true. If not, it terminates the execution and raises exception (which defaults to Timeout::Error).

Note that this is both a method of module Timeout, so you can 'include Timeout' into your classes so they have a timeout method, as well as a module method, so you can call it directly as ::timeout.

 
               # File timeout.rb, line 52
def timeout(sec, klass = nil)
  return yield if sec == nil or sec.zero?
  raise ThreadError, "timeout within critical session" if Thread.critical
  exception = klass || Class.new(ExitException)
  begin
    x = Thread.current
    y = Thread.start {
      begin
        sleep sec
      rescue => e
        x.raise e
      else
        x.raise exception, "execution expired" if x.alive?
      end
    }
    yield sec
    #    return true
  rescue exception => e
    rej = /\A#{Regexp.quote(__FILE__)}:#{__LINE__-4}\z/
    (bt = e.backtrace).reject! {|m| rej =~ m}
    level = -caller(CALLER_OFFSET).size
    while THIS_FILE =~ bt[level]
      bt.delete_at(level)
      level += 1
    end
    raise if klass            # if exception class is specified, it
                              # would be expected outside.
    raise Error, e.message, e.backtrace
  ensure
    if y and y.alive?
      y.kill
      y.join # make sure y is dead.
    end
  end
end