[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

open3 and background processes

Daniel Berger

8/26/2008 7:28:00 PM

Hi all,

I've got a poor man's init script where I'm firing off a Ruby process
in the background if it's not already running.

If the process fails, no problemo. The process I called dies, I pull
the error from the stderr handle via readlines, and fire off an email
to myself. But if the process succeeds, IO#readlines hangs because
there's no data to be read, so it just hangs there waiting for it.

One solution I came up with was to wrap the IO#readlines in a timeout,
but that feels clunky. Is there a better way to do this?

require 'open3'
require 'timeout'

program = File.join(Dir.pwd, "miniserver.rb")

cmd = "ruby #{program} &"

Open3.popen3(cmd) do |stdin, stdout, stderr|
begin
# Better way?
Timeout.timeout(2){
error = stderr.readlines
}
rescue Timeout::Error
puts "Timeout"
break
end

puts error.join("\n") if error
end

puts "Done"

Where "miniserver.rb" is just a simple loop/print/sleep program. I
thought there was a way to peek ahead on an IO object to see if any
data is available on the handle before attempting to read it, but
perhaps I'm glossing over the appropriate method.

Suggestions?

Thanks,

Dan

3 Answers

Gennady Bystritsky

8/26/2008 7:37:00 PM

0

IO.readlines will try to read out everything until EOF, hence it "hangs" fo=
r long running background processes. Can you use IO.readline instead and mo=
dify your spawned program to output a one line message to indicate success?=
Then it will catch both errors and successful runs.

Gennady.

> -----Original Message-----
> From: Daniel Berger [mailto:djberg96@gmail.com]
> Sent: Tuesday, August 26, 2008 12:28 PM
> To: ruby-talk ML
> Subject: open3 and background processes
>
> Hi all,
>
> I've got a poor man's init script where I'm firing off a Ruby process
> in the background if it's not already running.
>
> If the process fails, no problemo. The process I called dies, I pull
> the error from the stderr handle via readlines, and fire off an email
> to myself. But if the process succeeds, IO#readlines hangs because
> there's no data to be read, so it just hangs there waiting for it.
>
> One solution I came up with was to wrap the IO#readlines in a timeout,
> but that feels clunky. Is there a better way to do this?
>
> require 'open3'
> require 'timeout'
>
> program =3D File.join(Dir.pwd, "miniserver.rb")
>
> cmd =3D "ruby #{program} &"
>
> Open3.popen3(cmd) do |stdin, stdout, stderr|
> begin
> # Better way?
> Timeout.timeout(2){
> error =3D stderr.readlines
> }
> rescue Timeout::Error
> puts "Timeout"
> break
> end
>
> puts error.join("\n") if error
> end
>
> puts "Done"
>
> Where "miniserver.rb" is just a simple loop/print/sleep program. I
> thought there was a way to peek ahead on an IO object to see if any
> data is available on the handle before attempting to read it, but
> perhaps I'm glossing over the appropriate method.
>
> Suggestions?
>
> Thanks,
>
> Dan


Daniel Berger

8/26/2008 8:09:00 PM

0



On Aug 26, 1:37=A0pm, Gennady Bystritsky <Gennady.Bystrit...@quest.com>
wrote:
> IO.readlines will try to read out everything until EOF, hence it "hangs" =
for long running background processes. Can you use IO.readline instead and =
modify your spawned program to output a one line message to indicate succes=
s? Then it will catch both errors and successful runs.

Ah, ok. This seems to work fine:

program =3D File.join(Dir.pwd, "miniserver.rb")

cmd =3D "ruby #{program} &"

Open3.popen3(cmd) do |stdin, stdout, stderr|
# Use readline, since readlines waits until EOF
error =3D stderr.readline

if error
error =3D [error] << stderr.readlines # Get the rest
end

puts error if error
end

puts "Done"

Many thanks,

Dan

Gennady Bystritsky

8/28/2008 10:17:00 PM

0

> -----Original Message-----
> From: Daniel Berger [mailto:djberg96@gmail.com]
> Sent: Tuesday, August 26, 2008 1:09 PM
> To: ruby-talk ML
> Subject: Re: open3 and background processes
>
>
>
> On Aug 26, 1:37 pm, Gennady Bystritsky <Gennady.Bystrit...@quest.com>
> wrote:
> > IO.readlines will try to read out everything until EOF, hence it
> "hangs" for long running background processes. Can you use IO.readline
> instead and modify your spawned program to output a one line message to
> indicate success? Then it will catch both errors and successful runs.
>
> Ah, ok. This seems to work fine:
>
> program =3D File.join(Dir.pwd, "miniserver.rb")
>
> cmd =3D "ruby #{program} &"
>
> Open3.popen3(cmd) do |stdin, stdout, stderr|
> # Use readline, since readlines waits until EOF
> error =3D stderr.readline

The problem here is that if your miniserver.rb does not output anything to =
stderr in case of no error, stderr.readline will hang as well until it gets=
a newline. What I meant in my previous reply is that miniserver.rb must ou=
tput something like "SUCCESS" to stderr so that you can test for this in po=
pen3 block:

error =3D stderr.readline
unless error.chomp =3D=3D "SUCCESS
# process errors here
...
end

>
> if error
> error =3D [error] << stderr.readlines # Get the rest
> end
>
> puts error if error
> end
>
> puts "Done"
>
> Many thanks,
>
> Dan