Sha256: b397eaf0f00ba87eeb8c036300cd7bbc05356277d88949bdbdd63e322041007a
Contents?: true
Size: 1.88 KB
Versions: 3
Compression:
Stored size: 1.88 KB
Contents
# A helper class that allows you to run a block inside of a fork, and then get the result from that block. # # == Example: # # forker = Spork::Forker.new do # sleep 3 # "success" # end # # forker.result # => "success" class Spork::Forker # Raised if the fork died (was killed) before it sent it's response back. class ForkDiedException < Exception; end def initialize(&block) return unless block_given? @child_io, @server_io = UNIXSocket.socketpair @child_pid = Kernel.fork do begin @server_io.close Marshal.dump(yield, @child_io) # wait for the parent to acknowledge receipt of the result. master_response = Marshal.load(@child_io) rescue EOFError nil rescue SystemExit => e puts "Error: exit code #{e.status}" unless e.status == 0 rescue Exception => e puts "Exception encountered: #{e.inspect}\nbacktrace:\n#{e.backtrace * %(\n)}" end # terminate, skipping any at_exit blocks. exit!(0) end @child_io.close end # Wait for the fork to finish running, and then return its return value. # # If the fork was aborted, then result returns nil. def result return @result if defined?(@result) || ! running? result_thread = Thread.new do begin @result = Marshal.load(@server_io) Marshal.dump('ACK', @server_io) rescue EOFError @result = nil rescue ForkDiedException end end Process.wait(@child_pid) result_thread.raise(ForkDiedException) if result_thread.status == "sleep" @child_pid = nil @result end # abort the current running fork def abort if running? Process.kill(Signal.list['TERM'], @child_pid) @child_pid = nil true end end def running? return false unless @child_pid Process.getpgid(@child_pid) true rescue Errno::ESRCH false end end
Version data entries
3 entries across 3 versions & 1 rubygems
Version | Path |
---|---|
spork-1.0.0rc4 | lib/spork/forker.rb |
spork-1.0.0rc4-x86-mswin32 | lib/spork/forker.rb |
spork-1.0.0rc4-x86-mingw32 | lib/spork/forker.rb |