mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-08-10 00:01:27 -04:00
total_timeout does not rely on Timers#after
Instead, timeout accounting is done using total_timeout math. It supersedes all other timeouts in the connection, and will start from th moment the connection is established.
This commit is contained in:
parent
b0e057c15d
commit
9d861c3c2f
@ -70,6 +70,7 @@ module HTTPX
|
||||
|
||||
@inflight = 0
|
||||
@keep_alive_timeout = @options.timeout[:keep_alive_timeout]
|
||||
@total_timeout = @options.timeout[:total_timeout]
|
||||
|
||||
self.addresses = @options.addresses if @options.addresses
|
||||
end
|
||||
@ -230,6 +231,21 @@ module HTTPX
|
||||
end
|
||||
|
||||
def timeout
|
||||
if @total_timeout
|
||||
return @total_timeout unless @connected_at
|
||||
|
||||
elapsed_time = @total_timeout - (Process.clock_gettime(Process::CLOCK_MONOTONIC) - @connected_at)
|
||||
|
||||
if elapsed_time.negative?
|
||||
ex = TotalTimeoutError.new(@total_timeout, "Timed out after #{@total_timeout} seconds")
|
||||
ex.set_backtrace(error.backtrace)
|
||||
on_error(@total_timeout)
|
||||
return
|
||||
end
|
||||
|
||||
return elapsed_time
|
||||
end
|
||||
|
||||
return @timeout if defined?(@timeout)
|
||||
|
||||
return @options.timeout[:connect_timeout] if @state == :idle
|
||||
@ -459,11 +475,11 @@ module HTTPX
|
||||
when :open
|
||||
return if @state == :closed
|
||||
|
||||
total_timeout
|
||||
|
||||
@io.connect
|
||||
return unless @io.connected?
|
||||
|
||||
@connected_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
|
||||
send_pending
|
||||
|
||||
@timeout = @current_timeout = parser.timeout
|
||||
@ -475,11 +491,6 @@ module HTTPX
|
||||
return unless @state == :closing
|
||||
return unless @write_buffer.empty?
|
||||
|
||||
if @total_timeout
|
||||
@total_timeout.cancel
|
||||
remove_instance_variable(:@total_timeout)
|
||||
end
|
||||
|
||||
purge_after_closed
|
||||
when :already_open
|
||||
nextstate = :open
|
||||
@ -503,22 +514,25 @@ module HTTPX
|
||||
end
|
||||
|
||||
def handle_response
|
||||
@response_received_at = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
||||
@inflight -= 1
|
||||
end
|
||||
|
||||
def on_error(error)
|
||||
if error.instance_of?(TimeoutError)
|
||||
if @timeout
|
||||
@timeout -= error.timeout
|
||||
return unless @timeout <= 0
|
||||
end
|
||||
|
||||
if @total_timeout && @total_timeout.fires_in.negative?
|
||||
ex = TotalTimeoutError.new(@total_timeout.interval, "Timed out after #{@total_timeout.interval} seconds")
|
||||
if @total_timeout && @connected_at &&
|
||||
(Process.clock_gettime(Process::CLOCK_MONOTONIC) - @connected_at) > @total_timeout
|
||||
ex = TotalTimeoutError.new(@total_timeout, "Timed out after #{@total_timeout} seconds")
|
||||
ex.set_backtrace(error.backtrace)
|
||||
error = ex
|
||||
elsif connecting?
|
||||
error = error.to_connection_error
|
||||
else
|
||||
if @timeout
|
||||
@timeout -= error.timeout
|
||||
return unless @timeout <= 0
|
||||
end
|
||||
|
||||
error = error.to_connection_error if connecting?
|
||||
end
|
||||
end
|
||||
handle_error(error)
|
||||
@ -533,18 +547,5 @@ module HTTPX
|
||||
request.emit(:response, response)
|
||||
end
|
||||
end
|
||||
|
||||
def total_timeout
|
||||
total = @options.timeout[:total_timeout]
|
||||
|
||||
return unless total
|
||||
|
||||
@total_timeout ||= @timers.after(total) do
|
||||
ex = TotalTimeoutError.new(total, "Timed out after #{total} seconds")
|
||||
ex.set_backtrace(caller)
|
||||
on_error(ex)
|
||||
@parser.close if @parser
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user