diff --git a/History.txt b/History.txt index f86f03f..f90c62b 100644 --- a/History.txt +++ b/History.txt @@ -8,6 +8,8 @@ Breaking changes: New features: +* Added Net::HTTP::Persistent#max_retries= to configure the number of retries + performed on a request for ruby versions that support it (2.5+). * Use require_relative to reduce patch burden for vendored versions. Pull Request #106 by David Rodríguez * URI-ness is determined through #respond_to? to allow compatibility with diff --git a/lib/net/http/persistent.rb b/lib/net/http/persistent.rb index c7badfc..4a54118 100644 --- a/lib/net/http/persistent.rb +++ b/lib/net/http/persistent.rb @@ -299,6 +299,13 @@ def self.detect_idle_timeout uri, max = 10 attr_accessor :max_requests + ## + # Number of retries to perform if a request fails. + # + # See also #max_retries=, Net::HTTP#max_retries=. + + attr_reader :max_retries + ## # The value sent in the Keep-Alive header. Defaults to 30. Not needed for # HTTP/1.1 servers. @@ -476,6 +483,7 @@ def initialize name: nil, proxy: nil, pool_size: DEFAULT_POOL_SIZE @write_timeout = nil @idle_timeout = 5 @max_requests = nil + @max_retries = 1 @socket_options = [] @ssl_generation = 0 # incremented when SSL session variables change @@ -589,9 +597,11 @@ def connection_for uri reset connection end - http.read_timeout = @read_timeout if @read_timeout - http.write_timeout = @write_timeout if @write_timeout && http.respond_to?(:write_timeout=) - http.keep_alive_timeout = @idle_timeout if @idle_timeout + http.keep_alive_timeout = @idle_timeout if @idle_timeout + http.max_retries = @max_retries if http.respond_to?(:max_retries=) + http.read_timeout = @read_timeout if @read_timeout + http.write_timeout = @write_timeout if + @write_timeout && http.respond_to?(:write_timeout=) return yield connection rescue Errno::ECONNREFUSED @@ -678,6 +688,23 @@ def normalize_uri uri (uri =~ /^https?:/) ? uri : "http://#{uri}" end + ## + # Set the maximum number of retries for a request. + # + # Defaults to one retry. + # + # Set this to 0 to disable retries. + + def max_retries= retries + retries = retries.to_int + + raise ArgumentError, "max_retries must be positive" if retries < 0 + + @max_retries = retries + + reconnect + end + ## # Pipelines +requests+ to the HTTP server at +uri+ yielding responses if a # block is given. Returns all responses received. diff --git a/test/test_net_http_persistent.rb b/test/test_net_http_persistent.rb index fc010e0..a6124e8 100644 --- a/test/test_net_http_persistent.rb +++ b/test/test_net_http_persistent.rb @@ -248,6 +248,7 @@ def test_connection_for @http.open_timeout = 123 @http.read_timeout = 321 @http.idle_timeout = 42 + @http.max_retries = 5 used = @http.connection_for @uri do |c| assert_kind_of Net::HTTP, c.http @@ -258,6 +259,7 @@ def test_connection_for assert_equal 123, c.http.open_timeout assert_equal 321, c.http.read_timeout assert_equal 42, c.http.keep_alive_timeout + assert_equal 5, c.http.max_retries c end @@ -726,6 +728,13 @@ def test_http_version_IPv6 assert_equal '1.1', @http.http_version(@uri_v6) end + def test_max_retries_equals + @http.max_retries = 5 + + assert_equal 5, @http.max_retries + assert_equal 1, @http.generation + end + def test_normalize_uri assert_equal 'http://example', @http.normalize_uri('example') assert_equal 'http://example', @http.normalize_uri('http://example')