Module: Timeout

Defined in:
lib/rubysl/timeout/timeout.rb

Defined Under Namespace

Classes: Error, TimeoutRequest

Class Method Summary collapse

Class Method Details

.add_timeout(time, exc) ⇒ Object



127
128
129
130
131
# File 'lib/rubysl/timeout/timeout.rb', line 127

def self.add_timeout(time, exc)
  r = TimeoutRequest.new(time, Thread.current, exc)
  @chan << r
  return r
end

.timeout(sec, exception = Error) ⇒ Object

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.timeout().

Raises:

  • (ThreadError)


142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/rubysl/timeout/timeout.rb', line 142

def timeout(sec, exception=Error)
  return yield if sec == nil or sec.zero?
  raise ThreadError, "timeout within critical session" if Thread.respond_to?(:critical) && Thread.critical

  req = Timeout.add_timeout sec, exception

  begin
    yield sec
  ensure
    req.abort
  end
end

.watch_channelObject



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/rubysl/timeout/timeout.rb', line 84

def self.watch_channel
  reqs = []

  while true
    begin
      while reqs.empty?
        req = @chan.receive
        reqs << req if req
      end

      min = reqs.min { |a,b| a.left <=> b.left }
      new_req = nil

      if min.left > 0
        before = Time.now

        new_req = @chan.receive_timeout(min.left)

        slept_for = Time.now - before
      else
        slept_for = 0
      end

      reqs.delete_if do |r|
        if r.elapsed(slept_for)
          r.cancel
          true
        else
          false
        end
      end
      reqs << new_req if new_req

    rescue Exception => e
      e.render("ERROR IN TIMEOUT THREAD")
    end
  end
end