do not loop forever if there are no connections to listen nor any timer

to wait for.

Timeout calculation may trigger errors which lead to connection
unregistering, such as tital timeout errors. In such a case, we can end
up in a state where #select gets called with no timeout and no
selectable connections.

https://github.com/HoneyryderChuck/httpx/issues/3
This commit is contained in:
HoneyryderChuck 2021-12-09 13:40:38 +00:00
parent 8e77f0464a
commit edc2c4e6c4
2 changed files with 26 additions and 0 deletions

View File

@ -117,6 +117,13 @@ class HTTPX::Selector
end
def select(interval, &block)
# do not cause an infinite loop here.
#
# this may happen if timeout calculation actually triggered an error which causes
# the connections to be reaped (such as the total timeout error) before #select
# gets called.
return if interval.nil? && @selectables.empty?
return select_one(interval, &block) if @selectables.size == 1
select_many(interval, &block)

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
require "test_helper"
require "support/http_helpers"
require "support/minitest_extensions"
class Bug_0_18_2_Test < Minitest::Test
include HTTPHelpers
def test_no_loop_forever_when_total_timeout_on_persistent
session = HTTPX.plugin(:persistent).with_timeout(total_timeout: 1)
response1 = session.get("https://#{httpbin}/get")
sleep 2
response2 = session.get("https://#{httpbin}/get")
verify_status(response1, 200)
verify_status(response2, 200)
end
end