Gennady Bystritsky
8/26/2008 7:37:00 PM
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