Problem with method that starts process, yields pid then yields return code

Discussion in 'Ruby' started by x1, Dec 2, 2005.

  1. x1

    x1 Guest

    I'm trying to create a method that will kick off a new process, return
    it's pid.. while allowing the return code to also be captured for
    later examination..
    [on windows platform]

    class Exec
    def process_handler
    # if I do the following below, it will yield the
    # pid which is great, but because I did not
    # write pipe it to {}, I don't think it's possible to capture
    the return_level
    return IO.popen("ruby -e 'sleep 2' &exit 33").pid
    end
    end

    puts Exec.new.process_handler.to_s # =3D> 3389
    puts $? >> 8 # =3D> gives me an error because I didnt start IO.popen with {=
    }

    As a work around, I tried the following:
    class Exec
    def process_handler
    # if I do the following below, it will yield the
    # pid which is great, but because I did not
    # write pipe it to {}, I don't think it's possible to capture
    the return_level
    Thread.new {
    p =3D IO.popen("ruby -e 'sleep 2' &exit 33") {}
    $p_return_code =3D $? >> 8
    }
    return p, $p_return_code
    end
    end

    The problem here is, p will not be defined until the process has
    finished writing to the pipe {}, which will prevent the return of the
    pid..

    Any suggestions on this? I'm not able to test this code as I'm using
    a machine @ an internet cafe.

    Kind regards,
    Chris
    x1, Dec 2, 2005
    #1
    1. Advertising

  2. x1

    Guest

    Re: Problem with method that starts process, yields pid then yieldsreturn code

    On Fri, 2 Dec 2005, x1 wrote:

    > I'm trying to create a method that will kick off a new process, return it's
    > pid.. while allowing the return code to also be captured for later
    > examination.. [on windows platform]


    should work, but untested on windows:

    harp:~ > cat a.rb

    require "thread"
    class Exec
    %w( cmd queue pipe pid thread exitstatus ).each{|a| attr_accessor a}
    def initialize cmd
    self.cmd = cmd
    self.queue = ::Queue::new
    self.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
    self.pipe = queue.pop
    self.pid = queue.pop
    self.exitstatus = nil
    end
    def wait
    self.exitstatus = self.queue.pop
    end
    def self::[](*a, &b) new *a, &b end
    end

    require "yaml"

    y "start" => Time::now
    sleep = Exec[ " ruby -e' sleep 2 and exit 42 ' " ]
    y "cmd" => sleep.cmd
    y "pid" => sleep.pid
    y "exitstatus" => sleep.wait
    y "finish" => Time::now

    harp:~ > ruby a.rb
    ---
    start: 2005-12-02 14:03:29.920649 -07:00
    ---
    cmd: " ruby -e' sleep 2 and exit 42 ' "
    ---
    pid: 19947
    ---
    exitstatus: 42
    ---
    finish: 2005-12-02 14:03:31.930995 -07:00


    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
    ===============================================================================
    , Dec 2, 2005
    #2
    1. Advertising

  3. x1

    x1 Guest

    it seems to work!!

    Let me spend some time trying to make sense of it... Thanks
    soooooooooooooooo much!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    *grins*

    On 12/2/05, <> wrote:
    > On Fri, 2 Dec 2005, x1 wrote:
    >
    > > I'm trying to create a method that will kick off a new process, return =

    it's
    > > pid.. while allowing the return code to also be captured for later
    > > examination.. [on windows platform]

    >
    > should work, but untested on windows:
    >
    > harp:~ > cat a.rb
    >
    > require "thread"
    > class Exec
    > %w( cmd queue pipe pid thread exitstatus ).each{|a| attr_accessor a}
    > def initialize cmd
    > self.cmd =3D cmd
    > self.queue =3D ::Queue::new
    > self.thread =3D
    > ::Thread::new(queue) do |q|
    > pipe =3D ::IO::popen cmd
    > q.push pipe
    > q.push pipe.pid
    > begin
    > loop{ stdout =3D pipe.gets or break }
    > pipe.close
    > q.push $?.exitstatus
    > rescue =3D> e
    > q.push e
    > end
    > end
    > self.pipe =3D queue.pop
    > self.pid =3D queue.pop
    > self.exitstatus =3D nil
    > end
    > def wait
    > self.exitstatus =3D self.queue.pop
    > end
    > def self::[](*a, &b) new *a, &b end
    > end
    >
    > require "yaml"
    >
    > y "start" =3D> Time::now
    > sleep =3D Exec[ " ruby -e' sleep 2 and exit 42 ' " ]
    > y "cmd" =3D> sleep.cmd
    > y "pid" =3D> sleep.pid
    > y "exitstatus" =3D> sleep.wait
    > y "finish" =3D> Time::now
    >
    > harp:~ > ruby a.rb
    > ---
    > start: 2005-12-02 14:03:29.920649 -07:00
    > ---
    > cmd: " ruby -e' sleep 2 and exit 42 ' "
    > ---
    > pid: 19947
    > ---
    > exitstatus: 42
    > ---
    > finish: 2005-12-02 14:03:31.930995 -07:00
    >
    >
    > kind regards.
    >
    > -a
    > --
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    > | 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
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    >
    >
    >
    x1, Dec 3, 2005
    #3
  4. x1

    Guest

    Re: Problem with method that starts process, yields pid then yieldsreturn code

    On Sat, 3 Dec 2005, x1 wrote:

    > it seems to work!!
    >
    > Let me spend some time trying to make sense of it... Thanks
    > soooooooooooooooo much!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    > *grins*


    great.

    i learned a bit too : didn't know about pipe.pid

    cheers.

    -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
    ===============================================================================
    , Dec 3, 2005
    #4
  5. x1

    x1 Guest

    I've hacked at it and managed to learn quite a few things in the
    process but I cant seem to assign the Exec class to a DRb server to
    handle requests.

    Ideally, the <client> would be able to do something like:

    DRb.start_service
    sleep =3D DRbObject.new(nil, 'druby://server:2001').execute("ruby -e
    'sleep 3 and exit 43'")
    p sleep.pid
    p sleep.wait

    I tried everything I could think of but the script kept breaking.
    Here's what I've got that DOES work:

    require 'drb'
    require 'thread'

    class Execute
    =09%w( cmd queue pipe pid thread exitstatus alive ).each{|a| attr_accessor =
    a}
    =09def initialize(cmd)
    =09=09@cmd =3D cmd
    =09=09@queue =3D Queue.new
    =09=09@thread =3D Thread.new(queue) do |q|
    =09=09=09pipe =3D IO.popen(cmd)
    =09=09=09q.push pipe
    =09=09=09q.push pipe.pid
    =09=09=09begin
    =09=09=09=09loop{ stdout =3D pipe.gets or break }
    =09=09=09=09pipe.close
    =09=09=09=09q.push $?.exitstatus
    =09=09=09rescue =3D> e
    =09=09=09=09q.push e
    =09=09=09end
    =09=09end
    =09=09@pipe =3D queue.pop
    =09=09@pid =3D queue.pop
    =09=09@exitstatus =3D nil
    =09end
    =09def wait
    =09=09@exitstatus =3D @queue.pop
    =09end
    end

    hostname =3D `hostname`.chomp
    port =3D "4501"

    #DRb.start_service "druby://#{hostname}:#{port}", Execute.new
    #DRb.thread.join

    job =3D Execute.new("cmd /c ruby -e 'sleep 3 and exit 42'")
    puts job.cmd
    puts job.pid
    puts job.wait

    If I uncomment the DRb lines, the server starts but clients throw an error =
    :(



    On 12/2/05, <> wrote:
    > On Sat, 3 Dec 2005, x1 wrote:
    >
    > > it seems to work!!
    > >
    > > Let me spend some time trying to make sense of it... Thanks
    > > soooooooooooooooo much!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    > > *grins*

    >
    > great.
    >
    > i learned a bit too : didn't know about pipe.pid
    >
    > cheers.
    >
    > -a
    > --
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    > | 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
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    >
    >
    >
    x1, Dec 3, 2005
    #5
  6. x1

    Guest

    Re: Problem with method that starts process, yields pid then yieldsreturn code

    On Sun, 4 Dec 2005, x1 wrote:

    > I've hacked at it and managed to learn quite a few things in the
    > process but I cant seem to assign the Exec class to a DRb server to
    > handle requests.
    >
    > Ideally, the <client> would be able to do something like:


    <snip>

    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 = ARGV.shift
    hostname = Socket.gethostname
    port = 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 "exitstatus" => sleep.wait
    y "finish" => Time::now.iso8601
    end



    harp:~ > ./servant.rb server &
    [1] 15727



    harp:~ > ./servant.rb client
    ---
    start: "2005-12-03T16:58:19-07:00"
    ---
    pid: 15729
    ---
    exitstatus: 43
    ---
    finish: "2005-12-03T16:58:22-07:00"


    hth.


    -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
    ===============================================================================
    , Dec 3, 2005
    #6
  7. x1

    x1 Guest

    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.
    Here's my vision..



    class JobServer

    def execute(cmd)

    # kicks off the job and returns the pid

    return pid

    end

    def status(pid)

    # returns the status of the job. IE is the pid
    alive? or dead?

    return pid.alive?

    end

    def exitstatus(pid)

    # returns the exitstatus based on the PID

    return pid.exitstatus

    end

    end



    # Scenerio: I need to kick off two jobs and a third upon completion of
    the first (when exit statis is 0).

    # Ideally, one would be able to kick off a job with execute() and know
    about it's pid. Then later on, be able to reference the status of that
    pid, such as alive? or dead?. If dead, one could call the
    exitstatus() method to find out what the return code of that job was.



    case mode

    when %r/server/i

    DRb.start_service "druby://#{ hostname }:#{ port }"=
    ,

    JobServer.new

    DRb.thread.join

    when %r/client/i

    DRb.start_service

    job =3D DRbObject.new(nil, "druby://#{ hostname
    }:#{ port }")

    pid =3D job.execute("ruby -e' sleep 3 and exit 43 '=
    ")

    # without having to wait on the execution
    above to finish:

    if job.status(pid) =3D=3D true

    puts "exit status =3D " + job.existstat=
    us(pid)

    else

    puts "job still running"

    end

    end





    #Again, this code isnt functional, just a concept of how I would see.
    What's preventing me from turning waht we have into this is my lack of
    knowledge in the following w/ your code:

    # 1) not exactly sure attr_accessor does

    # 2) not sure what Queue.new does

    # 3) not sure what def initialize does



    # Again, I really=B2 appreciate your help in understanding and assistance.



    On 12/3/05, <> wrote:
    > On Sun, 4 Dec 2005, x1 wrote:
    >
    > > I've hacked at it and managed to learn quite a few things in the
    > > process but I cant seem to assign the Exec class to a DRb server to
    > > handle requests.
    > >
    > > Ideally, the <client> would be able to do something like:

    >
    > <snip>
    >
    > 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_acce=

    ssor a}
    > def initialize(cmd)
    > @cmd =3D cmd
    > @queue =3D Queue.new
    > @thread =3D Thread.new(queue) do |q|
    > pipe =3D IO.popen(cmd)
    > q.push pipe
    > q.push pipe.pid
    > begin
    > loop{ stdout =3D pipe.gets or break }
    > pipe.close
    > q.push $?.exitstatus
    > rescue =3D> e
    > q.push e
    > end
    > end
    > @pipe =3D queue.pop
    > @pid =3D queue.pop
    > @exitstatus =3D nil
    > end
    > def wait
    > @exitstatus =3D @queue.pop
    > end
    > end
    >
    > class Executioner
    > def execute cmd
    > Execute::new cmd
    > end
    > end
    >
    > mode =3D ARGV.shift
    > hostname =3D Socket.gethostname
    > port =3D 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 =3D DRbObject.new nil, "druby://#{ hostname }:#{ port=

    }"
    > sleep =3D executioner.execute "ruby -e' sleep 3 and exit 43 '"
    > y "start" =3D> Time::now.iso8601
    > y "pid" =3D> sleep.pid
    > y "exitstatus" =3D> sleep.wait
    > y "finish" =3D> Time::now.iso8601
    > end
    >
    >
    >
    > harp:~ > ./servant.rb server &
    > [1] 15727
    >
    >
    >
    > harp:~ > ./servant.rb client
    > ---
    > start: "2005-12-03T16:58:19-07:00"
    > ---
    > pid: 15729
    > ---
    > exitstatus: 43
    > ---
    > finish: "2005-12-03T16:58:22-07:00"
    >
    >
    > hth.
    >
    >
    > -a
    > --
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    > | 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
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    >
    >
    >
    x1, Dec 5, 2005
    #7
  8. x1

    Guest

    Re: Problem with method that starts process, yields pid then yieldsreturn code

    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
    , Dec 5, 2005
    #8
  9. x1

    x1 Guest

    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, <> 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_acces=

    sor a}
    > def initialize(cmd)
    > @cmd =3D cmd
    > @queue =3D Queue.new
    > @thread =3D Thread.new(queue) do |q|
    > pipe =3D IO.popen(cmd)
    > q.push pipe
    > q.push pipe.pid
    > begin
    > loop{ stdout =3D pipe.gets or break }
    > pipe.close
    > q.push $?.exitstatus
    > rescue =3D> e
    > q.push e
    > end
    > end
    > @pipe =3D queue.pop
    > @pid =3D queue.pop
    > @exitstatus =3D nil
    > end
    > def wait
    > @exitstatus =3D @queue.pop
    > end
    > end
    > class Executioner
    > def execute cmd
    > Execute::new cmd
    > end
    > end
    >
    > mode, hostname, port =3D ARGV.shift, Socket.gethostname, 4501
    >
    > case mode
    > when %r/server/i
    > DRb.start_service "druby://#{ hostname }:#{ port }", Executioner.n=

    ew
    > DRb.thread.join
    >
    > when %r/client/i
    > DRb.start_service
    > executioner =3D DRbObject.new nil, "druby://#{ hostname }:#{ port =

    }"
    > sleep =3D executioner.execute "ruby -e' sleep 3 and exit 43 '"
    > y "start" =3D> Time::now.iso8601
    > y "pid" =3D> sleep.pid
    > y "after getting pid..." =3D> Time::now.iso8601
    > y "exitstatus" =3D> sleep.wait
    > y "finish" =3D> 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
    > --
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    > | 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
    > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D
    >
    >
    > cat a.rb
    >
    >
    x1, Dec 6, 2005
    #9
  10. x1

    Guest

    Re: Problem with method that starts process, yields pid then yieldsreturn 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, <> 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
    ===============================================================================
    , Dec 6, 2005
    #10
  11. x1

    x1 Guest

    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 <> 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, <> wrote:
    > > On Tue, 6 Dec 2005, x1 wrote:
    > >
    > > > What we have so far works, however ideally, printing the pid should n=

    ot 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 completi=

    on (by
    > > definition) and is a blocking operation.
    > >
    > > before i read more of your post make sure you understand the above. th=

    e 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_acc=

    essor a}
    > > def initialize(cmd)
    > > @cmd =3D cmd
    > > @queue =3D Queue.new
    > > @thread =3D Thread.new(queue) do |q|
    > > pipe =3D IO.popen(cmd)
    > > q.push pipe
    > > q.push pipe.pid
    > > begin
    > > loop{ stdout =3D pipe.gets or break }
    > > pipe.close
    > > q.push $?.exitstatus
    > > rescue =3D> e
    > > q.push e
    > > end
    > > end
    > > @pipe =3D queue.pop
    > > @pid =3D queue.pop
    > > @exitstatus =3D nil
    > > end
    > > def wait
    > > @exitstatus =3D @queue.pop
    > > end
    > > end
    > > class Executioner
    > > def execute cmd
    > > Execute::new cmd
    > > end
    > > end
    > >
    > > mode, hostname, port =3D 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 =3D DRbObject.new nil, "druby://#{ hostname }:#{ por=

    t }"
    > > sleep =3D executioner.execute "ruby -e' sleep 3 and exit 43 '"
    > > y "start" =3D> Time::now.iso8601
    > > y "pid" =3D> sleep.pid
    > > y "after getting pid..." =3D> Time::now.iso8601
    > > y "exitstatus" =3D> sleep.wait
    > > y "finish" =3D> Time::now.iso8601
    > > end
    > >
    > >
    > > regarding your questions about 'initialize' and 'new' - ruby is object
    > > orientied. everything is an object constructed from a class. the meth=

    od new,
    > > when called on a class returns an object which was created an initializ=

    ed
    > > using it's initialize method. check out the 'pickaxe' and the 'ruby wa=

    y' for
    > > deep insight into ruby - you can't code without them.
    > >
    > > kind regards.
    > >
    > > -a
    > > --
    > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D
    > > | ara [dot] t [dot] howard [at] noaa [dot] gov
    > > | all happiness comes from the desire for others to be happy. all mise=

    ry
    > > | comes from the desire for oneself to be happy.
    > > | -- bodhicaryavatara
    > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D
    > >
    > >
    > > cat a.rb
    > >
    > >

    >
    >
    x1, Dec 6, 2005
    #11
  12. x1

    x1 Guest

    And here's the results from windows:

    Desktop>process.rb client
    starting @ Mon Dec 05 20:27:42 Eastern Standard Time 2005
    940
    Mon Dec 05 20:27:42 Eastern Standard Time 2005
    43
    Mon Dec 05 20:27:42 Eastern Standard Time 2005
    Finished @ Mon Dec 05 20:27:42 Eastern Standard Time 2005

    What's actually happening, is when this is executed:
    sleep =3D executioner.execute "ruby -e' sleep 3 and exit 43 '"

    Windows waits until the job finishes, and then continues to the next
    line...(no fork I guess) Just weird how it worked in the original
    example...

    On 12/5/05, x1 <> wrote:
    > 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 <> 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, <> 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 th=

    e
    > > > > 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 comple=

    tion (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_a=

    ccessor a}
    > > > def initialize(cmd)
    > > > @cmd =3D cmd
    > > > @queue =3D Queue.new
    > > > @thread =3D Thread.new(queue) do |q|
    > > > pipe =3D IO.popen(cmd)
    > > > q.push pipe
    > > > q.push pipe.pid
    > > > begin
    > > > loop{ stdout =3D pipe.gets or break }
    > > > pipe.close
    > > > q.push $?.exitstatus
    > > > rescue =3D> e
    > > > q.push e
    > > > end
    > > > end
    > > > @pipe =3D queue.pop
    > > > @pid =3D queue.pop
    > > > @exitstatus =3D nil
    > > > end
    > > > def wait
    > > > @exitstatus =3D @queue.pop
    > > > end
    > > > end
    > > > class Executioner
    > > > def execute cmd
    > > > Execute::new cmd
    > > > end
    > > > end
    > > >
    > > > mode, hostname, port =3D ARGV.shift, Socket.gethostname, 4501
    > > >
    > > > case mode
    > > > when %r/server/i
    > > > DRb.start_service "druby://#{ hostname }:#{ port }", Execution=

    er.new
    > > > DRb.thread.join
    > > >
    > > > when %r/client/i
    > > > DRb.start_service
    > > > executioner =3D DRbObject.new nil, "druby://#{ hostname }:#{ p=

    ort }"
    > > > sleep =3D executioner.execute "ruby -e' sleep 3 and exit 43 '"
    > > > y "start" =3D> Time::now.iso8601
    > > > y "pid" =3D> sleep.pid
    > > > y "after getting pid..." =3D> Time::now.iso8601
    > > > y "exitstatus" =3D> sleep.wait
    > > > y "finish" =3D> Time::now.iso8601
    > > > end
    > > >
    > > >
    > > > regarding your questions about 'initialize' and 'new' - ruby is objec=

    t
    > > > orientied. everything is an object constructed from a class. the me=

    thod new,
    > > > when called on a class returns an object which was created an initial=

    ized
    > > > 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
    > > > --
    > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D
    > > > | ara [dot] t [dot] howard [at] noaa [dot] gov
    > > > | all happiness comes from the desire for others to be happy. all mi=

    sery
    > > > | comes from the desire for oneself to be happy.
    > > > | -- bodhicaryavatara
    > > > =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=

    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
    =3D=3D=3D=3D=3D=3D
    > > >
    > > >
    > > > cat a.rb
    > > >
    > > >

    > >
    > >

    >
    >
    x1, Dec 6, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    615
    Mark Rae [MVP]
    Sep 5, 2007
  2. Etantonio
    Replies:
    3
    Views:
    561
    timjowers
    Apr 10, 2008
  3. P.S.
    Replies:
    0
    Views:
    317
  4. Miki Tebeka
    Replies:
    2
    Views:
    595
    Chris Angelico
    Apr 8, 2011
  5. Replies:
    0
    Views:
    273
Loading...

Share This Page