Search code examples
rubyscriptingpopen

How to check to see if ruby child process has completed without waiting


I'm aware that you can do something like this in ruby,

download_process = IO.popen "wget #{goodies}"
download_process.wait
puts "goodies gotten"

to spawn a subprocess and respond when it completes.

However, say I want to keep my script busy with other tasks whilst waiting for the child process to complete, then check back periodically whether any child processes have completed yet. How would I do this in ruby?

My goal is to have n simultaneous download threads, managed by a single ruby thread which also cleans up and processes the downloaded data files (so after processing a file it checks how many full downloaded files are waiting and decides how many download threads to spawn accordingly).


Solution

  • For this situation use IO.popen with block wrapped in a Thread. -q option added for this working example:

    file1 = "http://www.vim.org/scripts/download_script.php?src_id=7701"
    file2 = "http://www.openss7.org/repos/tarballs/strx25-0.9.2.1.tar.bz2"
    threads = []
    
    threads << Thread.new do
     IO.popen("wget -q   #{file1}"){ |io| io.read}
    end
    
    threads << Thread.new do
      IO.popen("wget -q  #{file2}"){ |io| io.read }
    end
    
    while true
      sleep(2)
      threads.each_with_index do |tr, index|
        if tr.alive?
          puts "Downloading in \##{index}"
        else
          puts "Downloaded in \##{index}"
          threads[index]  = Thread.new do
            IO.popen("wget -q   #{file1}"){ |io| io.read}
          end
        end
      end
    end