moved connection timeout counting to the channel; the timeout error also contains the interval that timed out; the bookkeeping is therefore kept by each channel

This commit is contained in:
HoneyryderChuck 2018-11-19 14:54:17 +00:00
parent cf46b530c1
commit 38e00d219f
4 changed files with 25 additions and 6 deletions

View File

@ -76,8 +76,9 @@ module HTTPX
@read_buffer = Buffer.new(BUFFER_SIZE)
@write_buffer = Buffer.new(BUFFER_SIZE)
@pending = []
@state = :idle
@timeout_manager = @options.timeout
on(:error) { |ex| on_error(ex) }
transition(:idle)
end
def addresses=(addrs)
@ -205,6 +206,17 @@ module HTTPX
@parser = build_parser(protocol)
end
def handle_timeout_error(e)
return emit(:error, e) unless @timeout
@timeout -= e.timeout
return unless @timeout <= 0
if connecting?
emit(:error, e.to_connection_error)
else
emit(:error, e)
end
end
private
def consume
@ -301,11 +313,13 @@ module HTTPX
# when :idle
when :idle
@error_response = nil
@timeout = @timeout_manager.connect_timeout
when :open
return if @state == :closed
@io.connect
return unless @io.connected?
send_pending
@timeout = nil
emit(:open)
when :closing
return unless @state == :open

View File

@ -34,9 +34,7 @@ module HTTPX
end
rescue TimeoutError => timeout_error
@channels.each do |ch|
error = timeout_error
error = error.to_connection_error if ch.connecting?
ch.emit(:error, error)
ch.handle_timeout_error(timeout_error)
end
rescue Errno::ECONNRESET,
Errno::ECONNABORTED,

View File

@ -6,8 +6,15 @@ module HTTPX
UnsupportedSchemeError = Class.new(Error)
TimeoutError = Class.new(Error) do
attr_reader :timeout
def initialize(timeout, message)
@timeout = timeout
super(message)
end
def to_connection_error
ex = ConnectTimeoutError.new(message)
ex = ConnectTimeoutError.new(@timeout, message)
ex.set_backtrace(backtrace)
ex
end

View File

@ -109,7 +109,7 @@ class HTTPX::Selector
readers, writers = IO.select(r, w, nil, interval)
raise HTTPX::TimeoutError, "timed out while waiting on select" if readers.nil? && writers.nil?
raise HTTPX::TimeoutError.new(interval, "timed out while waiting on select") if readers.nil? && writers.nil?
rescue IOError, SystemCallError
@lock.synchronize do
@readers.reject! { |io, _| io.closed? }