I think I’m about ready to give up on this approach given that JRuby
doesn’t claim to be able to fork. But I’d be interested if anyone had
an explanation for this behaviour, and whether there might be a
workaround.
Here’s reader1:
File.open(“testfile”, “w”) { |fh| fh.print “Hello World!” }
p $$
f1 = File.open(“testfile”)
print f1.sysread(6)
Process.waitpid2(fork { exec(“/usr/bin/ruby1.8”, “reader2”,
f1.fileno.to_s) })
Here’s reader2:
begin
f2 = IO.for_fd(ARGV[0].to_i)
print f2.sysread(6)
print “\n”
rescue Errno::EBADF => badf
print “File descriptor #{ARGV[0]}?\n”
end
p $$
So reader1 should open a file, display 6 bytes from it, and then pass
the same file handle to reader2 via fork/exec call, wait for the process
to exit, then exit itself.
The result under MRI is what I expect, two different process IDs and all
the data.
mattbee@desk4:~$ ruby reader1
26983
Hello World!
26984
JRuby 1.5.5 does this, and needs interrupting:
mattbee@desk4:~$ /usr/local/jruby-1.5.5/bin/jruby
-J-Djruby.fork.enabled=true reader1
WARNING: fork is highly unlikely to be safe or stable on the JVM.
Have fun!
27026
Hello File descriptor 4?
27054
^C
And my system JRuby (1.1.6) terminates, but gets muddled in a different
way:
mattbee@desk4:~$ jruby -J-Djruby.fork.enabled=true reader1
WARNING: fork is highly unlikely to be safe or stable on the JVM.
Have fun!
27110
Hello reader1:7: No child processes - No child processes
(Errno::ECHILD)
mattbee@desk4:~$ File descriptor 4?
27153
The fork is happening on JRuby, as I can see different pids but I’m not
sure why the same FD is invalid in the child process, and whether
there’s any point in trying to fix it.
If I take out the fork, and change reader1 to simply finish with:
exec(“/usr/bin/ruby1.8”, “reader2”, f1.fileno.to_s)
Then JRuby still gives me:
mattbee@desk4:~$ /usr/local/jruby-1.5.5/bin/jruby reader1
28969
Hello File descriptor 4?
28998
i.e. it gives me a new pid as if I had forked, and the same file
descriptor still isn’t valid.
Behind the scenes I see JRuby handing off to a POSIX library, which
looks like it is binding pretty directly to fork and exec. But if that
were happening it ought to work I think the correct answer is “stop
trying to supervise processes from Java” but I would be interested to
know if it ever could work, and why it doesn’t at the moment.
–
Matthew B. Bytemark Hosting
http://www.bytemark.co.uk/
tel: +44 (0) 1904 890890