class Aw::Fork

The Fork class.

@api private

Attributes

read[R]

@!attribute [r] read

@return [IO] The read endpoint.

write[R]

@!attribute [r] write

@return [IO] The write endpoint.

Public Class Methods

new(read, write) click to toggle source

Initialize the class.

@param read [IO] The read endpoint. @param write [IO] The write endpoint.

# File lib/aw/fork.rb, line 14
def initialize(read, write)
  # Currently, not available on all platforms.
  raise ::NotImplementedError, "fork()" unless ::Process.respond_to?(:fork)

  @read   = read
  @write  = write
end

Public Instance Methods

call(&block) click to toggle source

Runs the block inside a sub-process, and returns the computed value.

@example Computes ‘6 * 7` in a sub-process and returns `42` to the current process.

call { 6 * 7 } # => 42

@raise [Exception] Exceptions raised in a block of code are propagated. @return [#object_id] Returns the value that has been returned in the block.

# File lib/aw/fork.rb, line 39
def call(&block)
  pid = fork_and_return_pid(&block)
  write.close
  result = read.read
  ::Process.wait(pid)

  # rubocop:disable Security/MarshalLoad
  ::Marshal.load(result).tap { |r| raise r if r.is_a?(::Exception) }
  # rubocop:enable Security/MarshalLoad
end

Private Instance Methods

fork_and_return_pid() { || ... } click to toggle source

Creates a sub-process to execute a block inside, and returns the sub-process ID.

@return [Integer] The ID of the created sub-process.

# File lib/aw/fork.rb, line 56
def fork_and_return_pid
  ::Process.fork do
    # :nocov:

    read.close

    # rubocop:disable Lint/RescueException
    begin
      result = yield
    rescue ::Exception
      result = $ERROR_INFO
    end
    # rubocop:enable Lint/RescueException

    ::Marshal.dump(result, write)
    ::Process.exit!(true)

    # :nocov:
  end
end