superrip: limit maximum child processes
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Sat, 3 Apr 2010 20:27:22 +0000 (13:27 -0700)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Sat, 3 Apr 2010 20:27:22 +0000 (13:27 -0700)
superrip: limit the maximum number of child processes. Try to do too
many things at once can actually slow the system down because of
caching, etc. Also, do a waitall at the end of the script so that we can
be sure when we're done.

superrip.rb

index d069633..bdf7512 100755 (executable)
@@ -17,6 +17,7 @@ require 'ostruct'
 # constants
 #-----------------------------------------------------------------
 $cd_dev = "/dev/cdrom"
+$children = Hash.new
 
 #-----------------------------------------------------------------
 # functions
@@ -75,7 +76,12 @@ def audiorip(tnum, track)
   # cdparanoia always outputs to cdda.wav
   FileUtils.mv("cdda.wav", track.wav_file_name, $fu_args)
 
-  # TODO: if there are more than N processes, wait for one of them to terminate
+  # If there are too many processes, wait for one of them to terminate
+  if ($children.keys.length > $opts.max_children) then
+    pid = Process.wait(-1)
+    $children.delete(pid)
+  end
+
   pid = Process.fork
   if (pid == nil) then
     begin
@@ -84,6 +90,8 @@ def audiorip(tnum, track)
     rescue
       Kernel.exit(1)
     end
+  else
+    $children[pid] = 1
   end
 end
 
@@ -94,6 +102,7 @@ class MyOptions
   def self.parse(args)
     opts = OpenStruct.new
     opts.dry_run = false
+    opts.max_children = 4
     $fu_args = { :verbose => true }
 
     # Fill in opts values
@@ -115,6 +124,14 @@ class MyOptions
         opts.manifest_file = file
         opts.partial = true
       end
+      myparser.on("--max-children [NCHILD]", "-j",
+            "The maximum number of child processes to allow at any \
+given time") do |nchild|
+        opts.max_children = nchild.to_i
+        if (opts.max_children < 1) then
+          raise "can't set max_children to #{opts.max_children}"
+        end
+      end
     end
     parser.parse!(args)
 
@@ -184,6 +201,7 @@ class Manifest
       next unless @t.has_key?(tnum)
       audiorip(tnum, @t[tnum])
     end
+    Process.waitall
   end
 
   def inspect
@@ -218,4 +236,5 @@ puts manifest.inspect
 num_tracks = get_number_of_tracks_on_cd()
 puts "found #{num_tracks} tracks"
 manifest.rip(num_tracks)
+puts "*** FINISHED ***"
 exit 0