Class: WEBrick::Utils::TimeoutHandler
Relationships & Source Files | |
Namespace Children | |
Classes:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Instance Chain:
self,
Singleton
|
|
Inherits: | Object |
Defined in: | lib/webrick/utils.rb |
Overview
Class used to manage timeout handlers across multiple threads.
Timeout handlers should be managed by using the class methods which are synchronized.
id = TimeoutHandler.register(10, Timeout::Error)
begin
sleep 20
puts 'foo'
ensure
TimeoutHandler.cancel(id)
end
will raise Timeout::Error
id = TimeoutHandler.register(10, Timeout::Error)
begin
sleep 5
puts 'foo'
ensure
TimeoutHandler.cancel(id)
end
will print 'foo'
Class Method Summary
-
.cancel(id)
Cancels the timeout handler
id
-
.new ⇒ TimeoutHandler
constructor
Creates a new
TimeoutHandler
. -
.register(seconds, exception)
Registers a new timeout handler.
Instance Method Summary
-
#cancel(thread, id)
Cancels the timeout handler
id
-
#interrupt(thread, id, exception)
Interrupts the timeout handler
id
and raisesexception
-
#register(thread, time, exception)
Registers a new timeout handler.
Constructor Details
.new ⇒ TimeoutHandler
# File 'lib/webrick/utils.rb', line 151
def initialize TimeoutMutex.synchronize{ @timeout_info = Hash.new } @queue = Queue.new @watcher = Thread.start{ to_interrupt = [] while true now = Time.now wakeup = nil to_interrupt.clear TimeoutMutex.synchronize{ @timeout_info.each {|thread, ary| next unless ary ary.each{|info| time, exception = *info if time < now to_interrupt.push [thread, info.object_id, exception] elsif !wakeup || time < wakeup wakeup = time end } } } to_interrupt.each {|arg| interrupt(*arg)} if !wakeup @queue.pop elsif (wakeup -= now) > 0 begin (th = Thread.start {@queue.pop}).join(wakeup) ensure th&.kill&.join end end @queue.clear end } end
Class Method Details
.cancel(id)
Cancels the timeout handler id
# File 'lib/webrick/utils.rb', line 144
def TimeoutHandler.cancel(id) instance.cancel(Thread.current, id) end
.register(seconds, exception)
Registers a new timeout handler
time
-
Timeout in seconds
exception
-
Exception to raise when timeout elapsed
# File 'lib/webrick/utils.rb', line 138
def TimeoutHandler.register(seconds, exception) instance.register(Thread.current, Time.now + seconds, exception) end
Instance Method Details
#cancel(thread, id)
Cancels the timeout handler id
# File 'lib/webrick/utils.rb', line 215
def cancel(thread, id) TimeoutMutex.synchronize{ if ary = @timeout_info[thread] ary.delete_if{|info| info.object_id == id } if ary.empty? @timeout_info.delete(thread) end return true end return false } end
#interrupt(thread, id, exception)
Interrupts the timeout handler id
and raises exception
# File 'lib/webrick/utils.rb', line 192
def interrupt(thread, id, exception) if cancel(thread, id) && thread.alive? thread.raise(exception, "execution timeout") end end
#register(thread, time, exception)
Registers a new timeout handler
time
-
Timeout in seconds
exception
-
Exception to raise when timeout elapsed
# File 'lib/webrick/utils.rb', line 203
def register(thread, time, exception) info = nil TimeoutMutex.synchronize{ @timeout_info[thread] ||= Array.new @timeout_info[thread] << (info = [time, exception]) } @queue.push nil return info.object_id end