So... I just restarted and booted into SUSE.. The example works perfect under linux... --weird. To explain what I'm seeing, I added the output of Time.now directly after printing the pid & exit status.. linux>ruby process.rb client --- start: "2005-12-05T20:20:32-05:00" --- pid: 7712 --- x: "2005-12-05T20:20:32-05:00" --- exitstatus: 43 --- x: "2005-12-05T20:20:35-05:00" --- finish: "2005-12-05T20:20:35-05:00" As we see, it instantly gave me the pid and took two seconds to tell me the exitstatus. (which is what I want) but with windows, it takes 2 seconds to get anything back. I'll reboot and run the same script in windows.. On 12/5/05, x1 <caldridge / gmail.com> 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. > > On 12/5/05, ara.t.howard / noaa.gov <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 > > > > > >