class HTTP::Timeout::Global
Attributes
time_left[R]
total_timeout[R]
Public Class Methods
new(*args)
click to toggle source
Calls superclass method
# File lib/http/timeout/global.rb, line 12 def initialize(*args) super reset_counter end
Public Instance Methods
connect(socket_class, host, port, nodelay = false)
click to toggle source
# File lib/http/timeout/global.rb, line 23 def connect(socket_class, host, port, nodelay = false) reset_timer ::Timeout.timeout(time_left, TimeoutError) do @socket = socket_class.open(host, port) @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) if nodelay end log_time end
connect_ssl()
click to toggle source
# File lib/http/timeout/global.rb, line 33 def connect_ssl reset_timer begin @socket.connect_nonblock rescue IO::WaitReadable IO.select([@socket], nil, nil, time_left) log_time retry rescue IO::WaitWritable IO.select(nil, [@socket], nil, time_left) log_time retry end end
readpartial(size, buffer = nil)
click to toggle source
Read from the socket
# File lib/http/timeout/global.rb, line 50 def readpartial(size, buffer = nil) perform_io { read_nonblock(size, buffer) } end
reset_counter()
click to toggle source
To future me: Don't remove this again, past you was smarter.
# File lib/http/timeout/global.rb, line 18 def reset_counter @time_left = connect_timeout + read_timeout + write_timeout @total_timeout = time_left end
write(data)
click to toggle source
Write to the socket
# File lib/http/timeout/global.rb, line 55 def write(data) perform_io { write_nonblock(data) } end
Also aliased as: <<
Private Instance Methods
log_time()
click to toggle source
# File lib/http/timeout/global.rb, line 123 def log_time @time_left -= (Time.now - @started) if time_left <= 0 raise TimeoutError, "Timed out after using the allocated #{total_timeout} seconds" end reset_timer end
perform_io() { || ... }
click to toggle source
Perform the given I/O operation with the given argument
# File lib/http/timeout/global.rb, line 82 def perform_io reset_timer loop do begin result = yield case result when :wait_readable then wait_readable_or_timeout when :wait_writable then wait_writable_or_timeout when NilClass then return :eof else return result end rescue IO::WaitReadable wait_readable_or_timeout rescue IO::WaitWritable wait_writable_or_timeout end end rescue EOFError :eof end
read_nonblock(size, buffer = nil)
click to toggle source
# File lib/http/timeout/global.rb, line 64 def read_nonblock(size, buffer = nil) @socket.read_nonblock(size, buffer) end
reset_timer()
click to toggle source
Due to the run/retry nature of nonblocking I/O, it's easier to keep track of time via method calls instead of a block to monitor.
# File lib/http/timeout/global.rb, line 119 def reset_timer @started = Time.now end
wait_readable_or_timeout()
click to toggle source
Wait for a socket to become readable
# File lib/http/timeout/global.rb, line 106 def wait_readable_or_timeout @socket.to_io.wait_readable(time_left) log_time end
wait_writable_or_timeout()
click to toggle source
Wait for a socket to become writable
# File lib/http/timeout/global.rb, line 112 def wait_writable_or_timeout @socket.to_io.wait_writable(time_left) log_time end
write_nonblock(data)
click to toggle source
# File lib/http/timeout/global.rb, line 68 def write_nonblock(data) @socket.write_nonblock(data) end