Waiting for a popen4'd PID

Hi,

I’m writing a library that I want to work on both JRuby and MRI. The
purpose of the library is to provide ruby configuration and control
(start/stop) for an embedded server which runs in a separate process.

I’m trying to do this:

pid, sin, sout, serr = popen4(server_command) # from open4 for MRI,
IO.popen4 for JRuby

do stuff with in and out

Process.kill 15, pid
Process.waitpid2 pid

This works fine on MRI, but not on JRuby (testing on 1.5.2 on OS X). On
JRuby, I get Errno::ECHILD on the waitpid2 call. Is there a way to do
what I’m trying to do (start process with control of all streams; send a
signal; then wait until the process exits) in JRuby?

I’ve also considered using ProcessBuilder & Process, but there doesn’t
seem to be a way to initiate a graceful shutdown with Process. There’s
just #destroy (which is apparently signal 9) and no way to get the PID
to use kill. It looks like JRuby has code to extract the PID from a
process (ShellLauncher.getPidFromProcess), but I’m not sure if it is
part of the public API (is it?).

I’d appreciate any advice.

Thanks,
Rhett

Hi

did you try the Session gem? It works quite well on JRuby, we use it in
Redcar.

Regards,
Tim

Hi Tim,

On Oct 19, 2010, at 6:59 AM, Tim F. wrote:

Hi

did you try the Session gem? It works quite well on JRuby, we use it in Redcar.

Thanks for the suggestion, but session doesn’t seem to have a way to
send signals to the child processes (or to get their PIDs to do it
yourself). Am I missing something?

Rhett

This works fine on MRI, but not on JRuby (testing on 1.5.2 on OS X). On
JRuby, I get Errno::ECHILD on the waitpid2 call. Is there a way to do
what I’m trying to do (start process with control of all streams; send a
signal; then wait until the process exits) in JRuby?

It might be related to http://jira.codehaus.org/browse/JRUBY-4908
maybe spoon gem would help (?) (though not yet compat .with windows…)

Hi Roger,

On Oct 22, 2010, at 11:00 AM, Roger P. wrote:

This works fine on MRI, but not on JRuby (testing on 1.5.2 on OS X). On
JRuby, I get Errno::ECHILD on the waitpid2 call. Is there a way to do
what I’m trying to do (start process with control of all streams; send a
signal; then wait until the process exits) in JRuby?

It might be related to http://jira.codehaus.org/browse/JRUBY-4908
maybe spoon gem would help (?) (though not yet compat .with windows…)

Thanks for the suggestion. I don’t think that’s related, though – the
PIDs I was getting from IO.poen4 were the right ones.

Reading more and talking to a colleague, I learned that 1) popen4 is
usually implemented in terms of fork (including on MRI) and 2)
Process.waitpid2 only works with child (i.e., forked) processes. So the
particular flow from my original message is unlikely to work on JRuby
ever. I did get an alternative to work using the JDK’s ProcessBuilder
and JRuby’s ShellLauncher.getPidFromProcess. I’ve published the
library; for reference the relevant code is Ladle::JRubyProcess1,
which you can compare to Ladle::RubyProcess2.

The one remaining question I have is whether it’s okay to depend on
ShellLauncher.getPidFromProcess. I can’t tell whether it’s intended to
be internal-only or not.

Rhett

It might be related to http://jira.codehaus.org/browse/JRUBY-4908
maybe spoon gem would help (?) (though not yet compat .with windows…)

Thanks for the suggestion. I don’t think that’s related, though – the
PIDs I was getting from IO.poen4 were the right ones.

Looks like it’s related to http://jira.codehaus.org/browse/JRUBY-3780
then, I believe.