mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-10-05 00:02:38 -04:00
in a normal situation this would not happen, as events on a resolver would be dealt one at a time, but in a fiber-scheduler environment like async, the first query could be buffered in the 1st fiber switch, the second could then be enqueued on 2nd, then flush buffer and fiber switch on read, and a third query would then enter a corrupt state where, due to the buffer having been flushed on the 2nd fiber, write the 3rd query before receiving the second one, and messing up the pending query bookkeeping, making the fiber then block (due to DNS query never returning back) and expose that as an empty interest registration from some other connection on the selector this is fixed by using @timer as a proxy for knowing that a given DNS query has been flushed but is still waiting on a response (or an eventual retry)
74 lines
1.7 KiB
Plaintext
74 lines
1.7 KiB
Plaintext
module HTTPX
|
|
module Resolver
|
|
class Native < Resolver
|
|
extend Forwardable
|
|
include _ToIO
|
|
|
|
DEFAULTS: Hash[Symbol, untyped]
|
|
DNS_PORT: Integer
|
|
|
|
@options: Options
|
|
@ns_index: Integer
|
|
@nameserver: Array[String]
|
|
@socket_type: :udp | :tcp
|
|
@ndots: Integer
|
|
@start_timeout: Float?
|
|
@search: Array[String]
|
|
@_timeouts: Array[Numeric]
|
|
@timeouts: Hash[String, Array[Numeric]]
|
|
@queries: Hash[String, Connection]
|
|
@connections: Array[Connection]
|
|
@read_buffer: String
|
|
@write_buffer: Buffer
|
|
@large_packet: Buffer?
|
|
@io: UDP | TCP
|
|
@name: String?
|
|
@timer: Timers::Timer?
|
|
|
|
attr_reader state: Symbol
|
|
|
|
def call: () -> void
|
|
|
|
def interests: () -> (:r | :w | nil)
|
|
|
|
def <<: (Connection) -> void
|
|
|
|
def timeout: () -> Numeric?
|
|
|
|
def handle_socket_timeout: (Numeric interval) -> void
|
|
|
|
private
|
|
|
|
def initialize: (ip_family family, options options) -> void
|
|
|
|
def calculate_interests: () -> (:r | :w | nil)
|
|
|
|
def consume: () -> void
|
|
|
|
def schedule_retry: () -> void
|
|
|
|
def do_retry: (String host, Connection connection, Numeric interval) -> void
|
|
|
|
def dread: (Integer) -> void
|
|
| () -> void
|
|
|
|
def dwrite: () -> void
|
|
|
|
def parse: (String) -> void
|
|
|
|
def generate_candidates: (String) -> Array[String]
|
|
|
|
def build_socket: () -> (UDP | TCP)
|
|
|
|
def downgrade_socket: () -> void
|
|
|
|
def transition: (Symbol nextstate) -> void
|
|
|
|
def handle_error: (NativeResolveError | StandardError) -> void
|
|
|
|
def reset_hostname: (String hostname, ?connection: Connection, ?reset_candidates: bool) -> void
|
|
|
|
def close_or_resolve: () -> void
|
|
end
|
|
end
|
|
end |