mirror of
https://github.com/HoneyryderChuck/httpx.git
synced 2025-08-10 00:01:27 -04:00
66 lines
1.4 KiB
Ruby
66 lines
1.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "httpx/selector"
|
|
require "httpx/channel"
|
|
|
|
module HTTPX
|
|
class Connection
|
|
def initialize(options)
|
|
@options = Options.new(options)
|
|
@timeout = options.timeout
|
|
@selector = Selector.new
|
|
@channels = []
|
|
end
|
|
|
|
def running?
|
|
!@channels.empty?
|
|
end
|
|
|
|
def next_tick(timeout: @timeout.timeout)
|
|
@selector.select(timeout) do |monitor|
|
|
if (channel = monitor.value)
|
|
channel.call
|
|
end
|
|
monitor.interests = channel.interests
|
|
end
|
|
end
|
|
|
|
def close
|
|
@channels.each(&:close)
|
|
next_tick until @channels.empty?
|
|
end
|
|
|
|
def reset
|
|
@channels.each(&:reset)
|
|
end
|
|
|
|
def build_channel(uri, **options)
|
|
channel = Channel.by(uri, @options.merge(options))
|
|
register_channel(channel)
|
|
channel
|
|
end
|
|
|
|
# opens a channel to the IP reachable through +uri+.
|
|
# Many hostnames are reachable through the same IP, so we try to
|
|
# maximize pipelining by opening as few channels as possible.
|
|
#
|
|
def find_channel(uri)
|
|
@channels.find do |channel|
|
|
channel.match?(uri)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def register_channel(channel)
|
|
monitor = @selector.register(channel, :w)
|
|
monitor.value = channel
|
|
channel.on(:close) do
|
|
@channels.delete(channel)
|
|
@selector.deregister(channel)
|
|
end
|
|
@channels << channel
|
|
end
|
|
end
|
|
end
|