Skip to content

Commit 234f3b2

Browse files
authored
Merge pull request #131 from Shopify/handle-timeout-due-to-starvation
Handle timeout due to pool exhaustion
2 parents 431c024 + 6665d26 commit 234f3b2

File tree

3 files changed

+54
-36
lines changed

3 files changed

+54
-36
lines changed

History.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
=== 4.0.6 / 2024-12-04
2+
3+
Bug fixes:
4+
5+
* Allow ConnectionPool exceptions from checkout to bubble up to caller.
6+
17
=== 4.0.5 / 2024-12-04
28

39
Bug fixes:

lib/net/http/persistent.rb

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class Net::HTTP::Persistent
181181
##
182182
# The version of Net::HTTP::Persistent you are using
183183

184-
VERSION = '4.0.5'
184+
VERSION = '4.0.6'
185185

186186
##
187187
# Error class for errors raised by Net::HTTP::Persistent. Various
@@ -630,47 +630,49 @@ def connection_for uri
630630

631631
connection = @pool.checkout net_http_args
632632

633-
http = connection.http
633+
begin
634+
http = connection.http
634635

635-
connection.ressl @ssl_generation if
636-
connection.ssl_generation != @ssl_generation
636+
connection.ressl @ssl_generation if
637+
connection.ssl_generation != @ssl_generation
637638

638-
if not http.started? then
639-
ssl http if use_ssl
640-
start http
641-
elsif expired? connection then
642-
reset connection
643-
end
639+
if not http.started? then
640+
ssl http if use_ssl
641+
start http
642+
elsif expired? connection then
643+
reset connection
644+
end
644645

645-
http.keep_alive_timeout = @idle_timeout if @idle_timeout
646-
http.max_retries = @max_retries if http.respond_to?(:max_retries=)
647-
http.read_timeout = @read_timeout if @read_timeout
648-
http.write_timeout = @write_timeout if
649-
@write_timeout && http.respond_to?(:write_timeout=)
646+
http.keep_alive_timeout = @idle_timeout if @idle_timeout
647+
http.max_retries = @max_retries if http.respond_to?(:max_retries=)
648+
http.read_timeout = @read_timeout if @read_timeout
649+
http.write_timeout = @write_timeout if
650+
@write_timeout && http.respond_to?(:write_timeout=)
651+
652+
return yield connection
653+
rescue Errno::ECONNREFUSED
654+
if http.proxy?
655+
address = http.proxy_address
656+
port = http.proxy_port
657+
else
658+
address = http.address
659+
port = http.port
660+
end
650661

651-
return yield connection
652-
rescue Errno::ECONNREFUSED
653-
if http.proxy?
654-
address = http.proxy_address
655-
port = http.proxy_port
656-
else
657-
address = http.address
658-
port = http.port
659-
end
662+
raise Error, "connection refused: #{address}:#{port}"
663+
rescue Errno::EHOSTDOWN
664+
if http.proxy?
665+
address = http.proxy_address
666+
port = http.proxy_port
667+
else
668+
address = http.address
669+
port = http.port
670+
end
660671

661-
raise Error, "connection refused: #{address}:#{port}"
662-
rescue Errno::EHOSTDOWN
663-
if http.proxy?
664-
address = http.proxy_address
665-
port = http.proxy_port
666-
else
667-
address = http.address
668-
port = http.port
672+
raise Error, "host down: #{address}:#{port}"
673+
ensure
674+
@pool.checkin net_http_args
669675
end
670-
671-
raise Error, "host down: #{address}:#{port}"
672-
ensure
673-
@pool.checkin net_http_args
674676
end
675677

676678
##

test/test_net_http_persistent.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,16 @@ def test_connection_for
280280
assert_same used, stored
281281
end
282282

283+
def test_connection_for_exhaustion
284+
@http = Net::HTTP::Persistent.new pool_size: 0
285+
286+
assert_raises Timeout::Error do
287+
@http.connection_for @uri do |c|
288+
assert_same nil, c
289+
end
290+
end
291+
end
292+
283293
def test_connection_for_cached
284294
cached = basic_connection
285295
cached.http.start

0 commit comments

Comments
 (0)