In MRI Ruby I can do this:
def transfer
internal_server = self.init_server
pid = fork do
internal_server.run
end
# Make the server process run independently.
Process.detach(pid)
internal_client = self.init_client
# Do other stuff with connecting to internal_server...
internal_client.post('some data')
ensure
# Kill server
Process.kill('KILL', pid) if pid
end
However the above code will not run in jRuby, because it does not support 'fork' method:
NotImplementedError: fork is not available on this platform
Is there any alternative solution for this in jRuby?
Thanks.
This is a good question, but unfortunately I don't believe the JVM can safely give you what you want, if what you want is to start a new process that shares state with the parent process. That's because forking only copies the currently running thread. GC thread(s) for example, aren't copied. You don't want to be running a JVM without GC.
The only semi-safe way of using fork is to exec immediately afterwards.
Charles Nutter, on his blog, first says you can use FFI to fork and exec, but then provides a caveat:
The biggest problem with using fork+exec in this way is that you can't guarantee *nothing* happens between the fork call and the exec call. If, for example, the JVM decides to GC or move memory around, you can have a fatal crash at the JVM process level. Because of that, I don't recommend using fork + exec via FFI in JRuby, even though it's pretty cool.
I would tend to trust his advice here.
So, a fork and exec carries some risk, but keeping the forked JVM around is asking for trouble.
You should seriously consider the alternatives suggested by Sergio's comment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With