mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-12-08 00:00:58 -05:00
out with eden connections, keep closed around
connection bookkeeping on the pool changes, where all conections are kept around, even the ones that close during the scope of the requests; new requests may then find them, reset them, an reselect them. this is a major improvement, as objects get more reused, so less gc and object movement. this also changes the way pool terminates, as connections nonw follow a termination protocol, instead of just closing (which they can while scope is open)
This commit is contained in:
parent
b24ed83a8b
commit
ce7eb0b91a
@ -231,6 +231,12 @@ module HTTPX
|
||||
@parser.close if @parser
|
||||
end
|
||||
|
||||
def terminate
|
||||
@connected_at = nil if @state == :closed
|
||||
|
||||
close
|
||||
end
|
||||
|
||||
# bypasses the state machine to force closing of connections still connecting.
|
||||
# **only** used for Happy Eyeballs v2.
|
||||
def force_reset
|
||||
@ -580,14 +586,14 @@ module HTTPX
|
||||
when :inactive
|
||||
return unless @state == :open
|
||||
when :closing
|
||||
return unless @state == :open
|
||||
return unless @state == :idle || @state == :open
|
||||
|
||||
when :closed
|
||||
return unless @state == :closing
|
||||
return unless @write_buffer.empty?
|
||||
|
||||
purge_after_closed
|
||||
emit(:close)
|
||||
emit(:close) if @pending.empty?
|
||||
when :already_open
|
||||
nextstate = :open
|
||||
# the first check for given io readiness must still use a timeout.
|
||||
|
||||
@ -73,11 +73,11 @@ module HTTPX
|
||||
end
|
||||
|
||||
def close
|
||||
emit(:close)
|
||||
unless @connection.state == :closed
|
||||
@connection.goaway
|
||||
emit(:timeout, @options.timeout[:close_handshake_timeout])
|
||||
end
|
||||
emit(:close, true)
|
||||
end
|
||||
|
||||
def empty?
|
||||
|
||||
@ -17,8 +17,6 @@ module HTTPX
|
||||
@timers = Timers.new
|
||||
@selector = Selector.new
|
||||
@connections = []
|
||||
@eden_connections = []
|
||||
@connected_connections = 0
|
||||
end
|
||||
|
||||
def empty?
|
||||
@ -52,9 +50,8 @@ module HTTPX
|
||||
def close(connections = @connections)
|
||||
return if connections.empty?
|
||||
|
||||
@eden_connections.clear
|
||||
connections = connections.reject(&:inflight?)
|
||||
connections.each(&:close)
|
||||
connections.each(&:terminate)
|
||||
next_tick until connections.none? { |c| c.state != :idle && @connections.include?(c) }
|
||||
|
||||
# close resolvers
|
||||
@ -68,16 +65,13 @@ module HTTPX
|
||||
resolver.close unless resolver.closed?
|
||||
end
|
||||
# for https resolver
|
||||
resolver_connections.each(&:close)
|
||||
resolver_connections.each(&:terminate)
|
||||
next_tick until resolver_connections.none? { |c| c.state != :idle && @connections.include?(c) }
|
||||
end
|
||||
|
||||
def init_connection(connection, _options)
|
||||
resolve_connection(connection) unless connection.family
|
||||
connection.timers = @timers
|
||||
connection.on(:open) do
|
||||
@connected_connections += 1
|
||||
end
|
||||
connection.on(:activate) do
|
||||
select_connection(connection)
|
||||
end
|
||||
@ -98,6 +92,9 @@ module HTTPX
|
||||
connection.on(:close) do
|
||||
unregister_connection(connection)
|
||||
end
|
||||
connection.on(:terminate) do
|
||||
unregister_connection(connection, true)
|
||||
end
|
||||
end
|
||||
|
||||
def deactivate(connections)
|
||||
@ -116,16 +113,15 @@ module HTTPX
|
||||
connection.match?(uri, options)
|
||||
end
|
||||
|
||||
unless conn
|
||||
@eden_connections.delete_if do |connection|
|
||||
is_expired = connection.expired?
|
||||
conn = connection if conn.nil? && !is_expired && connection.match?(uri, options)
|
||||
is_expired
|
||||
end
|
||||
return unless conn
|
||||
|
||||
if conn
|
||||
case conn.state
|
||||
when :closed
|
||||
conn.idling
|
||||
select_connection(conn)
|
||||
when :closing
|
||||
conn.once(:close) do
|
||||
conn.idling
|
||||
@connections << conn
|
||||
select_connection(conn)
|
||||
end
|
||||
end
|
||||
@ -232,18 +228,12 @@ module HTTPX
|
||||
end
|
||||
|
||||
def register_connection(connection)
|
||||
if connection.state == :open
|
||||
# if open, an IO was passed upstream, therefore
|
||||
# consider it connected already.
|
||||
@connected_connections += 1
|
||||
end
|
||||
select_connection(connection)
|
||||
end
|
||||
|
||||
def unregister_connection(connection)
|
||||
@connections.delete(connection)
|
||||
@eden_connections << connection if connection.used? && !@eden_connections.include?(connection)
|
||||
@connected_connections -= 1 if deselect_connection(connection)
|
||||
def unregister_connection(connection, cleanup = !connection.used?)
|
||||
@connections.delete(connection) if cleanup
|
||||
deselect_connection(connection)
|
||||
end
|
||||
|
||||
def select_connection(connection)
|
||||
|
||||
@ -27,7 +27,7 @@ module HTTPX
|
||||
use_get: false,
|
||||
}.freeze
|
||||
|
||||
def_delegators :@resolver_connection, :state, :connecting?, :to_io, :call, :close
|
||||
def_delegators :@resolver_connection, :state, :connecting?, :to_io, :call, :close, :terminate
|
||||
|
||||
def initialize(_, options)
|
||||
super
|
||||
|
||||
@ -38,6 +38,8 @@ module HTTPX
|
||||
|
||||
def close; end
|
||||
|
||||
alias_method :terminate, :close
|
||||
|
||||
def closed?
|
||||
true
|
||||
end
|
||||
|
||||
@ -201,6 +201,7 @@ module HTTPX
|
||||
end
|
||||
|
||||
connection.merge(existing_connection)
|
||||
existing_connection.terminate
|
||||
connection
|
||||
rescue UnsupportedSchemeError
|
||||
altsvc["noop"] = true
|
||||
|
||||
@ -74,6 +74,8 @@ module HTTPX
|
||||
|
||||
def call: () -> void
|
||||
|
||||
def terminate: () -> void
|
||||
|
||||
def close: () -> void
|
||||
|
||||
def reset: () -> void
|
||||
|
||||
@ -6,8 +6,6 @@ module HTTPX
|
||||
@timers: Timers
|
||||
@selector: Selector
|
||||
@connections: Array[Connection]
|
||||
@eden_connections: Array[Connection]
|
||||
@connected_connections: Integer
|
||||
|
||||
def empty?: () -> void
|
||||
|
||||
@ -37,7 +35,7 @@ module HTTPX
|
||||
|
||||
def register_connection: (Connection) -> void
|
||||
|
||||
def unregister_connection: (Connection) -> void
|
||||
def unregister_connection: (Connection, ?bool cleanup) -> void
|
||||
|
||||
def select_connection: (Selector::selectable) -> void
|
||||
|
||||
|
||||
@ -14,6 +14,8 @@ module HTTPX
|
||||
|
||||
def close: () -> void
|
||||
|
||||
alias terminate close
|
||||
|
||||
def closed?: () -> bool
|
||||
|
||||
def empty?: () -> bool
|
||||
|
||||
@ -54,7 +54,8 @@ module Requests
|
||||
HTTPX.plugin(SessionWithPool).plugin(ResponseErrorEmitter).wrap do |http|
|
||||
response = http.get(uri)
|
||||
verify_error_response(response, "done with it")
|
||||
assert http.pool.connections.empty?
|
||||
assert http.pool.connections.size == 1
|
||||
assert http.pool.connections.first.state == :closed
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user