2012-08-05 5 views
5

W MRI Ruby mogę to zrobić:Alternatywa dla odrodzenia procesu z "widelcem" w jRuby?

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 

Jednakże powyższy kod nie będzie działał w JRuby, ponieważ nie obsługuje „widelec” metodę:

NotImplementedError: fork is not available on this platform 

Czy istnieją jakieś alternatywne rozwiązanie dla to w jRuby?

Dzięki.

+1

Odpowiedzi na [to pytanie] (http://stackoverflow.com/questions/5349629/ruby-daemons-and-jruby-alternative-options) mogą być dla Ciebie przydatne. –

+0

Dziękuję, [Łyżka] (https://github.com/headius/spoon) wydaje się interesująca, ale to nie rozwiązuje mojego problemu, ponieważ po prostu odradza się proces zewnętrzny bez dzielenia się stanem bieżącego wątku. W rzeczywistości potrzebuję "procesu potomnego" to inny interpreter Rubiego, a proces potomny będzie współdzielony z bieżącym wątkiem. –

+0

@ Odpowiedź Kelvina jest naprawdę dobra. Myślę, że warto zapytać, dlaczego chcesz się rozwidlić(). Funkcja fork() jest wywołaniem systemowym wbudowanym w systemy oparte na systemach uniksowych. Z drugiej strony Java ma być uruchamiana w dowolnym miejscu. Jeśli potrzebujesz rozwidlenia, sugerowałbym, że JRuby jest niewłaściwą implementacją ruby ​​dla ciebie. – Stewart

Odpowiedz

1

Dowiedziałem się o tym rozwiązanie. Możemy użyć wbudowanej biblioteki FFI w JRuby do "symulowania" pliku Process.fork w MRI.

# To mimic the Process.fork in MRI Ruby 
module JRubyProcess 
    require 'ffi' 
    extend FFI::Library 
    ffi_lib FFI::Library::LIBC 
    attach_function :fork, [], :int 
end 

pid = JRubyProcess.fork do 
    #internal_server.run 
end 

Więcej szczegółów:

https://github.com/ffi/ffi

http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html

+1

Charles Nutter sugeruje, że [niebezpieczny jest rozwidlenie za pomocą jruby] (https://github.com/jruby/jruby/issues/246), chyba że masz zamiar natychmiast wykonać polecenie.Wykonanie exec spowoduje wyjście rozwidlonej maszyny JVM, dlatego jest ona bezpieczna. – Kelvin

7

To jest dobre pytanie, ale niestety nie wierzę JVM można bezpiecznie dać ci to, co chcesz, jeśli to, co chcę, aby rozpocząć nowy proces, który dzieli stan z procesem nadrzędnym. Dzieje się tak, ponieważ rozwidlenie kopiuje tylko bieżący wątek. Wątki GC na przykład nie są kopiowane. Nie chcesz uruchamiać maszyny JVM bez GC.

Jedynym pół-bezpiecznym sposobem używania widelca jest natychmiastowe wykonanie.

Charles Nutter, na jego blog, najpierw mówi, można użyć FFI do stołu i exec, ale zapewnia zastrzeżenie:

Największym problemem przy użyciu widelca + exec w ten sposób, że można” t gwarancja * nic się nie dzieje między wywołaniem wywołania a wywołaniem exec. Jeśli na przykład maszyna JVM decyduje się na GC lub przenosi pamięć wokół, można przeprowadzić awarię na poziomie procesu JVM na poziomie . Z tego powodu, nie zalecam używania fork + exec przez FFI w JRuby, nawet jeśli jest to całkiem fajne, .

Byłbym skłonny zaufać jego rady tutaj.

Widelec i exec niesie ze sobą pewne ryzyko, ale utrzymanie rozwidlonej maszyny JVM wymaga kłopotów.

Powinieneś poważnie rozważyć alternatywy sugerowane przez komentarz Sergio.