From: x1 Date: 2005-12-06T09:33:46+09:00 Subject: Re: Problem with method that starts process, yields pid then yields return code weird thing is, with your first example, the pid prints out before the command finishes... where with the second example, nothing is printed out until the command exits. On 12/5/05, ara.t.howard@noaa.gov wrote: > On Tue, 6 Dec 2005, x1 wrote: > > > What we have so far works, however ideally, printing the pid should not rely > > on the completion of the job. The only thing that should rely on the > > completion of the job would be outputting the exitstatus. > > but that is the exactly the case? example: > > harp:~ > ruby servant.rb server & > [2] 31570 > > > harp:~ > ruby servant.rb client > --- > start: "2005-12-05T16:29:21-07:00" > --- > pid: 31572 > --- > after getting pid...: "2005-12-05T16:29:21-07:00" > --- > exitstatus: 43 > --- > finish: "2005-12-05T16:29:24-07:00" > > > note the times. __only__ getting the exitstatus relies on job completion (by > definition) and is a blocking operation. > > before i read more of your post make sure you understand the above. the code > again: > > harp:~ > cat servant.rb > #! /usr/bin/env ruby > %w( thread drb socket time yaml ).each{|lib| require lib} > class Execute > %w( cmd queue pipe pid thread exitstatus alive ).each{|a| attr_accessor a} > def initialize(cmd) > @cmd = cmd > @queue = Queue.new > @thread = Thread.new(queue) do |q| > pipe = IO.popen(cmd) > q.push pipe > q.push pipe.pid > begin > loop{ stdout = pipe.gets or break } > pipe.close > q.push $?.exitstatus > rescue => e > q.push e > end > end > @pipe = queue.pop > @pid = queue.pop > @exitstatus = nil > end > def wait > @exitstatus = @queue.pop > end > end > class Executioner > def execute cmd > Execute::new cmd > end > end > > mode, hostname, port = ARGV.shift, Socket.gethostname, 4501 > > case mode > when %r/server/i > DRb.start_service "druby://#{ hostname }:#{ port }", Executioner.new > DRb.thread.join > > when %r/client/i > DRb.start_service > executioner = DRbObject.new nil, "druby://#{ hostname }:#{ port }" > sleep = executioner.execute "ruby -e' sleep 3 and exit 43 '" > y "start" => Time::now.iso8601 > y "pid" => sleep.pid > y "after getting pid..." => Time::now.iso8601 > y "exitstatus" => sleep.wait > y "finish" => Time::now.iso8601 > end > > > regarding your questions about 'initialize' and 'new' - ruby is object > orientied. everything is an object constructed from a class. the method new, > when called on a class returns an object which was created an initialized > using it's initialize method. check out the 'pickaxe' and the 'ruby way' for > deep insight into ruby - you can't code without them. > > kind regards. > > -a > -- > =============================================================================== > | ara [dot] t [dot] howard [at] noaa [dot] gov > | all happiness comes from the desire for others to be happy. all misery > | comes from the desire for oneself to be happy. > | -- bodhicaryavatara > =============================================================================== > > > cat a.rb > >