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
>
>