Class: Async::Container::Process
- Defined in:
- lib/async/container/process.rb
Overview
Represents a running child process from the point of view of the parent container.
Defined Under Namespace
Classes: Instance
Instance Attribute Summary collapse
-
#name ⇒ Object
The name of the process.
Attributes inherited from Channel
Class Method Summary collapse
-
.fork(**options) ⇒ Object
Fork a child process appropriate for a container.
Instance Method Summary collapse
-
#close ⇒ Object
Invoke #terminate! and then #wait for the child process to exit.
-
#initialize(name: nil) ⇒ Process
constructor
Initialize the process.
-
#interrupt! ⇒ Object
Send ‘SIGINT` to the child process.
-
#terminate! ⇒ Object
Send ‘SIGTERM` to the child process.
-
#to_s ⇒ Object
A human readable representation of the process.
-
#wait ⇒ Object
Wait for the child process to exit.
Methods inherited from Channel
#close_read, #close_write, #receive
Constructor Details
#initialize(name: nil) ⇒ Process
Initialize the process.
98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/async/container/process.rb', line 98 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 |
Instance Attribute Details
#name ⇒ Object
The name of the process.
122 123 124 |
# File 'lib/async/container/process.rb', line 122 def name @name end |
Class Method Details
.fork(**options) ⇒ Object
Fork a child process appropriate for a container.
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/async/container/process.rb', line 66 def self.fork(**) self.new(**) 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 |
Instance Method Details
#close ⇒ Object
Invoke #terminate! and then #wait for the child process to exit.
131 132 133 134 135 136 |
# File 'lib/async/container/process.rb', line 131 def close self.terminate! self.wait ensure super end |
#interrupt! ⇒ Object
Send ‘SIGINT` to the child process.
139 140 141 142 143 |
# File 'lib/async/container/process.rb', line 139 def interrupt! unless @status ::Process.kill(:INT, @pid) end end |
#terminate! ⇒ Object
Send ‘SIGTERM` to the child process.
146 147 148 149 150 |
# File 'lib/async/container/process.rb', line 146 def terminate! unless @status ::Process.kill(:TERM, @pid) end end |
#to_s ⇒ Object
A human readable representation of the process.
126 127 128 |
# File 'lib/async/container/process.rb', line 126 def to_s "\#<#{self.class} #{@name}>" end |
#wait ⇒ Object
Wait for the child process to exit.
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/async/container/process.rb', line 154 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 |