Last active
February 8, 2023 01:36
-
-
Save rickhull/4ea71e1bdc02f55174fbdcf3bae4930d to your computer and use it in GitHub Desktop.
Happy Eyeballs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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