Module: Timeout
- Defined in:
- lib/rubysl/timeout/timeout.rb
Defined Under Namespace
Classes: Error, TimeoutRequest
Class Method Summary collapse
- .add_timeout(time, exc) ⇒ Object
-
.timeout(sec, exception = Error) ⇒ Object
Executes the method’s block.
- .watch_channel ⇒ Object
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().
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_channel ⇒ Object
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 |