Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Problem with method that starts process, yields pid then yields return code

Reply
Thread Tools

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

 
 
x1
Guest
Posts: n/a
 
      12-02-2005
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


 
Reply With Quote
 
 
 
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-02-2005
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:open 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
================================================== =============================



 
Reply With Quote
 
 
 
 
x1
Guest
Posts: n/a
 
      12-03-2005
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:open 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=3 D=3D=3D=3D=3D=3D=3D=3D=

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

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>
>
>



 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-03-2005
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
================================================== =============================



 
Reply With Quote
 
x1
Guest
Posts: n/a
 
      12-03-2005
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=3 D=3D=3D=3D=3D=3D=3D=3D=

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

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>
>
>



 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-03-2005
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
================================================== =============================



 
Reply With Quote
 
x1
Guest
Posts: n/a
 
      12-05-2005
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=3 D=3D=3D=3D=3D=3D=3D=3D=

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

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3 D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D
>
>
>



 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-05-2005
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


 
Reply With Quote
 
x1
Guest
Posts: n/a
 
      12-06-2005
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=3 D=3D=3D=3D=3D=3D=3D=3D=

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

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



 
Reply With Quote
 
ara.t.howard@noaa.gov
Guest
Posts: n/a
 
      12-06-2005
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
================================================== =============================



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
problem in running a basic code in python 3.3.0 that includes HTML file Satabdi Mukherjee Python 1 04-04-2013 07:48 PM
[ANN] Roxy 0.1 - Remote Proxy Objects w/ type & method signature impersonation and w/ remote block yields. Jeff Wood Ruby 7 10-18-2005 06:51 AM
Re: Firefox starts, then takes up entire screen - bug? Leonidas Jones Firefox 0 09-19-2005 12:47 PM
Help. SessionID is x then y then x then y BodiKlamph@gmail.com ASP General 0 09-03-2005 03:02 PM
Instant Messenger starts when Outlook Express 6 starts no matter what is checked! Route9w Computer Support 11 07-08-2004 01:13 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57