Skip to content

Instantly share code, notes, and snippets.

@rickhull
Last active February 8, 2023 01:36
Show Gist options
  • Save rickhull/4ea71e1bdc02f55174fbdcf3bae4930d to your computer and use it in GitHub Desktop.
Save rickhull/4ea71e1bdc02f55174fbdcf3bae4930d to your computer and use it in GitHub Desktop.
Happy Eyeballs
require 'thread'
class ThreadInterrupt < RuntimeError; end
def try_ip
if rand(2).zero?
sleep 0.5
true
else
sleep(rand(5) + 1)
false
end
end
def cleanup
:noop
end
def eyeball(ip_list)
success = false
threads = []
ip_list.each.with_index { |ip, idx|
if !success # skip future ips if we've succeeded
# wait 1 second before trying the next IP
sleep 1 if idx > 0
if !success # skip creating a thread if we've succeeded
puts "trying #{ip}"
threads << Thread.new {
Thread.handle_interrupt(ThreadInterrupt => :never) {
puts "in a thread"
if !success # skip trying an ip if we've succeeded
begin
Thread.handle_interrupt(ThreadInterrupt => :immediate) {
success = ip if try_ip
puts "success: #{success}"
}
rescue ThreadInterrupt
puts "received ThreadInterrupt"
ensure
Thread.handle_interrupt(ThreadInterrupt => :never) { cleanup }
end
end
}
}
end
end
}
if success # skip waiting for threads to finish
threads.each { |t| t.raise(ThreadInterrupt) }
end
threads.each(&:join)
success
end
eyeball [1, 10, 100, 100]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment