Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alternative for spawning a process with 'fork' in jRuby?

Tags:

ruby

jruby

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.

like image 715
Blue Smith Avatar asked Aug 05 '12 17:08

Blue Smith


1 Answers

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.

like image 75
Kelvin Avatar answered Sep 27 '22 15:09

Kelvin