introduce :buffer_size option

this allows to tweak connection buffer sizes, which may help optimizing
memory usage, and in this case, test the resumable retries.

wip
This commit is contained in:
HoneyryderChuck 2023-04-17 02:37:18 +03:00
parent cb523794d7
commit 8105e1128e
6 changed files with 27 additions and 9 deletions

View File

@ -39,8 +39,6 @@ module HTTPX
require "httpx/connection/http2" require "httpx/connection/http2"
require "httpx/connection/http1" require "httpx/connection/http1"
BUFFER_SIZE = 1 << 14
def_delegator :@io, :closed? def_delegator :@io, :closed?
def_delegator :@write_buffer, :empty? def_delegator :@write_buffer, :empty?
@ -57,8 +55,8 @@ module HTTPX
@origin = Utils.to_uri(uri.origin) @origin = Utils.to_uri(uri.origin)
@options = Options.new(options) @options = Options.new(options)
@window_size = @options.window_size @window_size = @options.window_size
@read_buffer = Buffer.new(BUFFER_SIZE) @read_buffer = Buffer.new(@options.buffer_size)
@write_buffer = Buffer.new(BUFFER_SIZE) @write_buffer = Buffer.new(@options.buffer_size)
@pending = [] @pending = []
on(:error, &method(:on_error)) on(:error, &method(:on_error))
if @options.io if @options.io

View File

@ -4,6 +4,7 @@ require "socket"
module HTTPX module HTTPX
class Options class Options
BUFFER_SIZE = 1 << 14
WINDOW_SIZE = 1 << 14 # 16K WINDOW_SIZE = 1 << 14 # 16K
MAX_BODY_THRESHOLD_SIZE = (1 << 10) * 112 # 112K MAX_BODY_THRESHOLD_SIZE = (1 << 10) * 112 # 112K
CONNECT_TIMEOUT = 60 CONNECT_TIMEOUT = 60
@ -41,6 +42,7 @@ module HTTPX
}, },
:headers => {}, :headers => {},
:window_size => WINDOW_SIZE, :window_size => WINDOW_SIZE,
:buffer_size => BUFFER_SIZE,
:body_threshold_size => MAX_BODY_THRESHOLD_SIZE, :body_threshold_size => MAX_BODY_THRESHOLD_SIZE,
:request_class => Class.new(Request), :request_class => Class.new(Request),
:response_class => Class.new(Response), :response_class => Class.new(Response),
@ -178,7 +180,19 @@ module HTTPX
end end
def option_window_size(value) def option_window_size(value)
Integer(value) value = Integer(value)
raise TypeError, ":window_size must be positive" unless value.positive?
value
end
def option_buffer_size(value)
value = Integer(value)
raise TypeError, ":buffer_size must be positive" unless value.positive?
value
end end
def option_body_threshold_size(value) def option_body_threshold_size(value)

View File

@ -19,7 +19,6 @@ module HTTPX
include Callbacks include Callbacks
include HTTPX::Registry[String, Class] include HTTPX::Registry[String, Class]
BUFFER_SIZE: Integer
attr_reader type: io_type attr_reader type: io_type
attr_reader origin: URI::Generic attr_reader origin: URI::Generic

View File

@ -2,6 +2,7 @@ module HTTPX
class Options class Options
# include _ToHash # include _ToHash
BUFFER_SIZE: Integer
WINDOW_SIZE: Integer WINDOW_SIZE: Integer
MAX_BODY_THRESHOLD_SIZE: Integer MAX_BODY_THRESHOLD_SIZE: Integer
CONNECT_TIMEOUT: Integer CONNECT_TIMEOUT: Integer
@ -38,6 +39,9 @@ module HTTPX
# window_size # window_size
attr_reader window_size: Integer attr_reader window_size: Integer
# buffer_size
attr_reader buffer_size: Integer
# body_threshold_size # body_threshold_size
attr_reader body_threshold_size: Integer attr_reader body_threshold_size: Integer

View File

@ -100,6 +100,7 @@ class OptionsTest < Minitest::Test
:json => nil, :json => nil,
:xml => nil, :xml => nil,
:body => nil, :body => nil,
:buffer_size => 16_384,
:window_size => 16_384, :window_size => 16_384,
:body_threshold_size => 114_688, :body_threshold_size => 114_688,
:form => { foo: "foo", :bar => "bar" }, :form => { foo: "foo", :bar => "bar" },

View File

@ -98,7 +98,7 @@ module Requests
end end
def test_plugin_retries_resumable def test_plugin_retries_resumable
resumable_uri = build_uri("/range/200") resumable_uri = build_uri("/range/200?chunk_size=100")
full_payload = HTTPX.get(resumable_uri).raise_for_status.to_s full_payload = HTTPX.get(resumable_uri).raise_for_status.to_s
retries_session = HTTPX retries_session = HTTPX
@ -106,7 +106,9 @@ module Requests
.plugin(RequestFailAfter100Bytes) .plugin(RequestFailAfter100Bytes)
.plugin(:retries) .plugin(:retries)
.max_retries(2) .max_retries(2)
.with(retry_on: ->(res) { res.error.is_a?(RequestFailAfter100Bytes::BiggerThan100Bytes) }, window_size: 100) .with(retry_on: ->(res) {
res.error && res.error.message == "over 100 bytes"
}, window_size: 50, buffer_size: 50, http2_settings: { settings_initial_window_size: 100 })
retries_response = retries_session.get(resumable_uri) retries_response = retries_session.get(resumable_uri)
verify_status(retries_response, 200) verify_status(retries_response, 200)
assert retries_response.to_s == full_payload assert retries_response.to_s == full_payload
@ -128,7 +130,7 @@ module Requests
def write(chunk) def write(chunk)
val = super val = super
raise(BiggerThan100Bytes, "ouch") if (100..199).cover?(@length) raise(BiggerThan100Bytes, "over 100 bytes") if (100..199).cover?(@length)
val val
end end