mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-21 04:42:56 +08:00
The current default timeout is hardcoded to 2 seconds which is proving too low for certain cases, and resulting in sporadic timeouts due to slow DNS queries.
66 lines
1.3 KiB
Ruby
Vendored
66 lines
1.3 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
class FinalDestination::Resolver
|
|
@mutex = Mutex.new
|
|
def self.lookup(addr, timeout: nil)
|
|
timeout ||= default_dns_query_timeout
|
|
|
|
@mutex.synchronize do
|
|
@result = nil
|
|
|
|
@queue ||= Queue.new
|
|
ensure_lookup_thread
|
|
|
|
@lookup = addr
|
|
@parent = Thread.current
|
|
|
|
# Wakeup the worker thread
|
|
@queue << ""
|
|
|
|
# This sleep will be interrupted by the lookup thread
|
|
# if completed within timeout
|
|
sleep timeout
|
|
if !@result
|
|
@thread.kill
|
|
@thread.join
|
|
@thread = nil
|
|
if @error
|
|
@error.backtrace.push(*caller)
|
|
raise @error
|
|
else
|
|
raise Timeout::Error
|
|
end
|
|
end
|
|
@result
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def self.default_dns_query_timeout
|
|
if gs = GlobalSetting.dns_query_timeout_secs.presence
|
|
Integer(gs)
|
|
else
|
|
2
|
|
end
|
|
end
|
|
|
|
def self.ensure_lookup_thread
|
|
return if @thread&.alive?
|
|
|
|
@thread =
|
|
Thread.new do
|
|
while true
|
|
@queue.deq
|
|
@error = nil
|
|
begin
|
|
@result = Addrinfo.getaddrinfo(@lookup, 80, nil, :STREAM).map(&:ip_address)
|
|
rescue => e
|
|
@error = e
|
|
end
|
|
@parent.wakeup
|
|
end
|
|
end
|
|
@thread.name = "final-destination_resolver_thread"
|
|
end
|
|
end
|