class Process
Represents a running child process from the point of view of the parent container.
Nested
Definitions
def self.fork(**options)
Fork a child process appropriate for a container.
Signature
-
returns
Process
Implementation
def self.fork(**options)
self.new(**options) do |process|
::Process.fork do
# We use `Thread.current.raise(...)` so that exceptions are filtered through `Thread.handle_interrupt` correctly.
Signal.trap(:INT) {::Thread.current.raise(Interrupt)}
Signal.trap(:TERM) {::Thread.current.raise(Terminate)}
begin
yield Instance.for(process)
rescue Interrupt
# Graceful exit.
rescue Exception => error
Console.logger.error(self) {error}
exit!(1)
end
end
end
end
def initialize(name: nil)
Initialize the process.
Signature
-
parameter
name
String
The name to use for the child process.
Implementation
def initialize(name: nil)
super()
@name = name
@status = nil
@pid = nil
@pid = yield(self)
# The parent process won't be writing to the channel:
self.close_write
end
def name= value
Set the name of the process.
Invokes ::Process.setproctitle
if invoked in the child process.
Implementation
def name= value
@name = value
# If we are the child process:
::Process.setproctitle(@name) if @pid.nil?
end
attr :name
The name of the process.
Signature
-
attribute
String
def to_s
A human readable representation of the process.
Signature
-
returns
String
Implementation
def to_s
"\#<#{self.class} #{@name}>"
end
def close
Invoke #terminate!
and then #wait
for the child process to exit.
Implementation
def close
self.terminate!
self.wait
ensure
super
end
def interrupt!
Send SIGINT
to the child process.
Implementation
def interrupt!
unless @status
::Process.kill(:INT, @pid)
end
end
def terminate!
Send SIGTERM
to the child process.
Implementation
def terminate!
unless @status
::Process.kill(:TERM, @pid)
end
end
def wait
Wait for the child process to exit.
Signature
-
returns
::Process::Status
The process exit status.
Implementation
def wait
if @pid && @status.nil?
_, @status = ::Process.wait2(@pid, ::Process::WNOHANG)
if @status.nil?
sleep(0.01)
_, @status = ::Process.wait2(@pid, ::Process::WNOHANG)
end
if @status.nil?
Console.logger.warn(self) {"Process #{@pid} is blocking, has it exited?"}
_, @status = ::Process.wait2(@pid)
end
end
return @status
end