diff --git a/lib/httpx.rb b/lib/httpx.rb index 15d86e8c..30b6ba37 100644 --- a/lib/httpx.rb +++ b/lib/httpx.rb @@ -13,7 +13,6 @@ require "httpx/loggable" require "httpx/registry" require "httpx/transcoder" require "httpx/options" -require "httpx/timeout" require "httpx/pool" require "httpx/headers" require "httpx/request" diff --git a/lib/httpx/connection.rb b/lib/httpx/connection.rb index 198a98b1..761946b4 100644 --- a/lib/httpx/connection.rb +++ b/lib/httpx/connection.rb @@ -69,7 +69,7 @@ module HTTPX end @inflight = 0 - @keep_alive_timeout = options.timeout.keep_alive_timeout + @keep_alive_timeout = options.timeout[:keep_alive_timeout] @keep_alive_timer = nil self.addresses = options.addresses if options.addresses @@ -238,9 +238,9 @@ module HTTPX def timeout return @timeout if defined?(@timeout) - return @options.timeout.connect_timeout if @state == :idle + return @options.timeout[:connect_timeout] if @state == :idle - @options.timeout.operation_timeout + @options.timeout[:operation_timeout] end private @@ -451,7 +451,7 @@ module HTTPX def transition(nextstate) case nextstate when :idle - @timeout = @current_timeout = @options.timeout.connect_timeout + @timeout = @current_timeout = @options.timeout[:connect_timeout] when :open return if @state == :closed @@ -463,7 +463,7 @@ module HTTPX send_pending - @timeout = @current_timeout = @options.timeout.operation_timeout + @timeout = @current_timeout = @options.timeout[:operation_timeout] emit(:open) when :closing return unless @state == :open @@ -547,7 +547,7 @@ module HTTPX end def total_timeout - total = @options.timeout.total_timeout + total = @options.timeout[:total_timeout] return unless total diff --git a/lib/httpx/io/tcp.rb b/lib/httpx/io/tcp.rb index b6e71740..08bcfd4d 100644 --- a/lib/httpx/io/tcp.rb +++ b/lib/httpx/io/tcp.rb @@ -63,7 +63,7 @@ module HTTPX @ip_index -= 1 retry rescue Errno::ETIMEDOUT => e - raise ConnectTimeoutError.new(@options.timeout.connect_timeout, e.message) if @ip_index <= 0 + raise ConnectTimeoutError.new(@options.timeout[:connect_timeout], e.message) if @ip_index <= 0 @ip_index -= 1 retry diff --git a/lib/httpx/options.rb b/lib/httpx/options.rb index d2917d48..065c513c 100644 --- a/lib/httpx/options.rb +++ b/lib/httpx/options.rb @@ -4,6 +4,9 @@ module HTTPX class Options WINDOW_SIZE = 1 << 14 # 16K MAX_BODY_THRESHOLD_SIZE = (1 << 10) * 112 # 112K + CONNECT_TIMEOUT = 60 + OPERATION_TIMEOUT = 60 + KEEP_ALIVE_TIMEOUT = 20 class << self def new(options = {}) @@ -51,7 +54,11 @@ module HTTPX :ssl => {}, :http2_settings => { settings_enable_push: 0 }, :fallback_protocol => "http/1.1", - :timeout => Timeout.new, + :timeout => { + connect_timeout: CONNECT_TIMEOUT, + operation_timeout: OPERATION_TIMEOUT, + keep_alive_timeout: KEEP_ALIVE_TIMEOUT, + }, :headers => {}, :window_size => WINDOW_SIZE, :body_threshold_size => MAX_BODY_THRESHOLD_SIZE, @@ -90,7 +97,14 @@ module HTTPX OUT def_option(:timeout, <<-OUT) - Timeout.new(value) + timeouts = Hash[value] + + if timeouts.key?(:loop_timeout) + warn ":loop_timeout is deprecated, use :operation_timeout instead" + timeouts[:operation_timeout] = timeouts.delete(:loop_timeout) + end + + timeouts OUT def_option(:max_concurrent_requests, <<-OUT) diff --git a/lib/httpx/timeout.rb b/lib/httpx/timeout.rb deleted file mode 100644 index 593c0ebf..00000000 --- a/lib/httpx/timeout.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: true - -require "timeout" - -module HTTPX - class Timeout - CONNECT_TIMEOUT = 60 - OPERATION_TIMEOUT = 60 - KEEP_ALIVE_TIMEOUT = 20 - - def self.new(opts = {}) - return opts if opts.is_a?(Timeout) - - super(**opts) - end - - attr_reader :connect_timeout, :operation_timeout, :keep_alive_timeout, :total_timeout - - def initialize(connect_timeout: CONNECT_TIMEOUT, - operation_timeout: OPERATION_TIMEOUT, - keep_alive_timeout: KEEP_ALIVE_TIMEOUT, - total_timeout: nil, - loop_timeout: nil) - @connect_timeout = connect_timeout - @operation_timeout = operation_timeout - @keep_alive_timeout = keep_alive_timeout - @total_timeout = total_timeout - - return unless loop_timeout - - # :nocov: - warn ":loop_timeout is deprecated, use :operation_timeout instead" - @operation_timeout = loop_timeout - # :nocov: - end - - def ==(other) - if other.is_a?(Timeout) - @connect_timeout == other.instance_variable_get(:@connect_timeout) && - @operation_timeout == other.instance_variable_get(:@operation_timeout) && - @keep_alive_timeout == other.instance_variable_get(:@keep_alive_timeout) && - @total_timeout == other.instance_variable_get(:@total_timeout) - else - super - end - end - - def merge(other) - case other - when Hash - timeout = Timeout.new(other) - merge(timeout) - when Timeout - connect_timeout = other.instance_variable_get(:@connect_timeout) || @connect_timeout - operation_timeout = other.instance_variable_get(:@operation_timeout) || @operation_timeout - keep_alive_timeout = other.instance_variable_get(:@keep_alive_timeout) || @keep_alive_timeout - total_timeout = other.instance_variable_get(:@total_timeout) || @total_timeout - Timeout.new(connect_timeout: connect_timeout, - operation_timeout: operation_timeout, - keep_alive_timeout: keep_alive_timeout, - total_timeout: total_timeout) - else - raise ArgumentError, "can't merge with #{other.class}" - end - end - end -end diff --git a/sig/options.rbs b/sig/options.rbs index 477c3ed3..7146db43 100644 --- a/sig/options.rbs +++ b/sig/options.rbs @@ -5,6 +5,9 @@ module HTTPX WINDOW_SIZE: Integer MAX_BODY_THRESHOLD_SIZE: Integer + type timeout_type = :connect_timeout | :operation_timeout | :keep_alive_timeout | :total_timeout + type timeout = Hash[timeout_type, Numeric?] + def self.new: (options) -> instance | () -> instance @@ -13,8 +16,8 @@ module HTTPX def headers=: (headers) -> void # timeout - attr_reader timeout: Timeout? - def timeout=: (Hash[Symbol, untyped] | Timeout) -> void + attr_reader timeout: timeout + def timeout=: (timeout) -> void # max_concurrent_requests attr_reader max_concurrent_requests: Integer? diff --git a/sig/timeout.rbs b/sig/timeout.rbs deleted file mode 100644 index aaa8235a..00000000 --- a/sig/timeout.rbs +++ /dev/null @@ -1,29 +0,0 @@ -module HTTPX - class Timeout - CONNECT_TIMEOUT: Numeric - KEEP_ALIVE_TIMEOUT: Numeric - OPERATION_TIMEOUT: Numeric - - attr_reader connect_timeout: Numeric - attr_reader operation_timeout: Numeric - attr_reader total_timeout: Numeric? - attr_reader keep_alive_timeout: Numeric? - - def self.new: (instance | Hash[Symbol, untyped]) -> instance - | () -> instance - - def ==: (untyped other) -> bool - - def merge: (Timeout | Hash[Symbol, untyped]) -> instance - - private - - def initialize: ( - ?connect_timeout: Numeric, - ?operation_timeout: Numeric, - ?keep_alive_timeout: Numeric, - ?total_timeout: Numeric | nil, - ?loop_timeout: Numeric | nil - ) -> untyped - end -end diff --git a/test/options_test.rb b/test/options_test.rb index 8f100675..26ad3365 100644 --- a/test/options_test.rb +++ b/test/options_test.rb @@ -89,7 +89,11 @@ class OptionsTest < Minitest::Test :window_size => 16_384, :body_threshold_size => 114_688, :form => { :bar => "bar" }, - :timeout => Timeout.new, + :timeout => { + connect_timeout: 60, + operation_timeout: 60, + keep_alive_timeout: 20, + }, :ssl => { :foo => "bar" }, :http2_settings => { :settings_enable_push => 0 }, :fallback_protocol => "http/1.1",