From: ara.t.howard@... Date: 2005-12-06T10:21:54+09:00 Subject: Re: Problem with method that starts process, yields pid then yields return code On Tue, 6 Dec 2005, x1 wrote: > 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. trying putting STDOUT.sync = true at the top of the script. > > 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 >> >> > > -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 ===============================================================================