# frozen_string_literal: true class FinalDestination::Resolver @mutex = Mutex.new def self.lookup(addr, timeout: nil) timeout ||= 2 @mutex.synchronize do @result = nil @queue ||= Queue.new @queue << "" ensure_lookup_thread @lookup = addr @parent = Thread.current # 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.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