Compare commits

...

9 Commits

Author SHA1 Message Date
HoneyryderChuck
2de2b026be bump release to 1.0.2 2023-10-13 18:12:20 +01:00
HoneyryderChuck
9d3dd72b80 fixing datadog min version 2023-10-13 18:06:33 +01:00
HoneyryderChuck
c1da8d29fc readded support for older datadog versions... 2023-10-13 17:52:42 +01:00
HoneyryderChuck
1fa9846f56 set min versio of http-2-next to 1.0.1 2023-10-13 17:04:11 +01:00
HoneyryderChuck
ba6fc820b7 bump version to 0.24.7 2023-10-13 16:55:09 +01:00
HoneyryderChuck
16ecdd2b57 readded support for older datadog versions... 2023-10-13 16:54:22 +01:00
HoneyryderChuck
2896134f67 Merge branch 'http-2-next-patch' into 'master'
http/2: do not interpret MAX_CONCURRENT_STREAMS as request cap

See merge request os85/httpx!278
2023-10-13 15:07:34 +00:00
HoneyryderChuck
97a34cfcbc wip: using master 2023-10-13 15:56:10 +01:00
HoneyryderChuck
ca75148e86 http/2: do not interpret MAX_CONCURRENT_STREAMS as request cap
a misinterpretation of the spec on http-2-next led to the introduction
of the max_requests option, a cap of requests on a given connection,
which in http/2 case, would be initialized with MAX_CONCURRENT_STREAMS,
which means something else.

This has been fixed already in http-2-next, and this is the summary of
changes required to support it.

The `max_requests` option is kept, as it can still be useful from a user
perspective, but the default in http/2 is now INFINITY, which disables
it effectively. The HTTP/1 cap is bumped to 200, but it may fall as
well soon.
2023-10-13 15:56:10 +01:00
9 changed files with 61 additions and 59 deletions

View File

@ -0,0 +1,10 @@
# 0.24.6
## dependencies
`http-2-next` last supported version for the 0.x series is the last version before v1. This shoul ensure that older versions of `httpx` won't be affected by any of the recent breaking changes.
## Bugfixes
* `grpc`: setup of rpc calls from camel-cased symbols has been fixed. As an improvement, the GRPC-enabled session will now support both snake-cased, as well as camel-cased calls.
* `datadog` adapter has now been patched to support the most recent breaking changes of `ddtrace` configuration DSL (`env_to_bool` is no longer supported).

View File

@ -0,0 +1,7 @@
# 1.0.2
## bugfixes
* bump `http-2-next` to 1.0.1, which fixes a bug where http/2 connection interprets MAX_CONCURRENT_STREAMS as request cap.
* `grpc`: setup of rpc calls from camel-cased symbols has been fixed. As an improvement, the GRPC-enabled session will now support both snake-cased, as well as camel-cased calls.
* `datadog` adapter has now been patched to support the most recent breaking changes of `ddtrace` configuration DSL (`env_to_bool` is no longer supported).

View File

@ -32,7 +32,7 @@ Gem::Specification.new do |gem|
gem.require_paths = ["lib"] gem.require_paths = ["lib"]
gem.add_runtime_dependency "http-2-next", ">= 1.0.0" gem.add_runtime_dependency "http-2-next", ">= 1.0.1"
gem.required_ruby_version = ">= 2.7.0" gem.required_ruby_version = ">= 2.7.0"
end end

View File

@ -126,6 +126,7 @@ module Datadog::Tracing
option :distributed_tracing, default: true option :distributed_tracing, default: true
option :split_by_domain, default: false option :split_by_domain, default: false
if DDTrace::VERSION::STRING >= "1.13.0"
option :enabled do |o| option :enabled do |o|
o.type :bool o.type :bool
o.env "DD_TRACE_HTTPX_ENABLED" o.env "DD_TRACE_HTTPX_ENABLED"
@ -143,6 +144,22 @@ module Datadog::Tracing
o.env "DD_TRACE_HTTPX_ANALYTICS_SAMPLE_RATE" o.env "DD_TRACE_HTTPX_ANALYTICS_SAMPLE_RATE"
o.default 1.0 o.default 1.0
end end
else
option :enabled do |o|
o.default { env_to_bool("DD_TRACE_HTTPX_ENABLED", true) }
o.lazy
end
option :analytics_enabled do |o|
o.default { env_to_bool(%w[DD_TRACE_HTTPX_ANALYTICS_ENABLED DD_HTTPX_ANALYTICS_ENABLED], false) }
o.lazy
end
option :analytics_sample_rate do |o|
o.default { env_to_float(%w[DD_TRACE_HTTPX_ANALYTICS_SAMPLE_RATE DD_HTTPX_ANALYTICS_SAMPLE_RATE], 1.0) }
o.lazy
end
end
if defined?(Datadog::Tracing::Contrib::SpanAttributeSchema) if defined?(Datadog::Tracing::Contrib::SpanAttributeSchema)
option :service_name do |o| option :service_name do |o|
@ -170,11 +187,13 @@ module Datadog::Tracing
o.type :proc o.type :proc
o.default_proc(&DEFAULT_ERROR_HANDLER) o.default_proc(&DEFAULT_ERROR_HANDLER)
end end
else elsif DDTrace::VERSION::STRING >= "1.13.0"
option :error_handler do |o| option :error_handler do |o|
o.type :proc o.type :proc
o.experimental_default_proc(&DEFAULT_ERROR_HANDLER) o.experimental_default_proc(&DEFAULT_ERROR_HANDLER)
end end
else
option :error_handler, default: DEFAULT_ERROR_HANDLER
end end
end end
end end
@ -205,7 +224,7 @@ module Datadog::Tracing
class Integration class Integration
include Contrib::Integration include Contrib::Integration
MINIMUM_VERSION = Gem::Version.new("1.0.1") MINIMUM_VERSION = Gem::Version.new("0.10.2")
register_as :httpx register_as :httpx

View File

@ -7,7 +7,7 @@ module HTTPX
include Callbacks include Callbacks
include Loggable include Loggable
MAX_REQUESTS = 100 MAX_REQUESTS = 200
CRLF = "\r\n" CRLF = "\r\n"
attr_reader :pending, :requests attr_reader :pending, :requests

View File

@ -35,7 +35,7 @@ module HTTPX
@handshake_completed = false @handshake_completed = false
@wait_for_handshake = @settings.key?(:wait_for_handshake) ? @settings.delete(:wait_for_handshake) : true @wait_for_handshake = @settings.key?(:wait_for_handshake) ? @settings.delete(:wait_for_handshake) : true
@max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS @max_concurrent_requests = @options.max_concurrent_requests || MAX_CONCURRENT_REQUESTS
@max_requests = @options.max_requests || 0 @max_requests = @options.max_requests || Float::INFINITY
init_connection init_connection
end end
@ -82,9 +82,7 @@ module HTTPX
end end
def exhausted? def exhausted?
return false if @max_requests.zero? && @connection.active_stream_count.zero? !@max_requests.positive?
@connection.active_stream_count >= @max_requests
end end
def <<(data) def <<(data)
@ -92,13 +90,9 @@ module HTTPX
end end
def can_buffer_more_requests? def can_buffer_more_requests?
if @handshake_completed (@handshake_completed || !@wait_for_handshake) &&
@streams.size < @max_concurrent_requests && @streams.size < @max_concurrent_requests &&
@streams.size < @max_requests @streams.size < @max_requests
else
!@wait_for_handshake &&
@streams.size < @max_concurrent_requests
end
end end
def send(request) def send(request)
@ -116,7 +110,6 @@ module HTTPX
true true
rescue HTTP2Next::Error::StreamLimitExceeded rescue HTTP2Next::Error::StreamLimitExceeded
@pending.unshift(request) @pending.unshift(request)
emit(:exhausted)
end end
def consume def consume
@ -172,7 +165,6 @@ module HTTPX
def init_connection def init_connection
@connection = HTTP2Next::Client.new(@settings) @connection = HTTP2Next::Client.new(@settings)
@connection.max_streams = @max_requests if @connection.respond_to?(:max_streams=) && @max_requests.positive?
@connection.on(:frame, &method(:on_frame)) @connection.on(:frame, &method(:on_frame))
@connection.on(:frame_sent, &method(:on_frame_sent)) @connection.on(:frame_sent, &method(:on_frame_sent))
@connection.on(:frame_received, &method(:on_frame_received)) @connection.on(:frame_received, &method(:on_frame_received))
@ -340,14 +332,7 @@ module HTTPX
def on_settings(*) def on_settings(*)
@handshake_completed = true @handshake_completed = true
emit(:current_timeout) emit(:current_timeout)
@max_concurrent_requests = [@max_concurrent_requests, @connection.remote_settings[:settings_max_concurrent_streams]].min
if @max_requests.zero?
@max_requests = @connection.remote_settings[:settings_max_concurrent_streams]
@connection.max_streams = @max_requests if @connection.respond_to?(:max_streams=) && @max_requests.positive?
end
@max_concurrent_requests = [@max_concurrent_requests, @max_requests].min
send_pending send_pending
end end

View File

@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module HTTPX module HTTPX
VERSION = "1.0.1" VERSION = "1.0.2"
end end

View File

@ -114,7 +114,7 @@ class HTTPSTest < Minitest::Test
def test_http2_max_streams def test_http2_max_streams
uri = build_uri("/get") uri = build_uri("/get")
HTTPX.plugin(SessionWithSingleStream).plugin(SessionWithPool).wrap do |http| HTTPX.plugin(SessionWithPool).with(max_requests: 1).wrap do |http|
http.get(uri, uri) http.get(uri, uri)
connection_count = http.pool.connection_count connection_count = http.pool.connection_count
assert connection_count == 2, "expected to have 2 connections, instead have #{connection_count}" assert connection_count == 2, "expected to have 2 connections, instead have #{connection_count}"

View File

@ -1,19 +0,0 @@
# frozen_string_literal: true
#
# This module is used only to test transitions from a full HTTP/2 connection when it
# exhausts the number of streamss
#
module SessionWithSingleStream
module ConnectionMethods
def build_parser
parser = super
def parser.exhausted?
@connection.active_stream_count.positive?
end
parser.instance_variable_set(:@max_requests, 10)
parser.instance_variable_get(:@connection).max_streams = 1
parser
end
end
end