We build a small project that watches multiple metrics until one of them finds something, I found ThreadsWait in the stdlib and it was easy to use it. Also added error re-raising so the threads do not die silently and cleanup.
require 'thwait' def wait_for_first_block_to_complete(*blocks) threads = blocks.map do |block| Thread.new do block.call rescue StandardError => e e end end waiter = ThreadsWait.new(*threads) value = waiter.next_wait.value threads.each(&:kill) raise value if value.is_a?(StandardError) value end wait_for_first_block_to_complete( -> { sleep 5 }, -> { sleep 1 }, -> { sleep 2 } ) # will stop after 1 second