Class: Mutant::Isolation::Fork Private
- Inherits:
-
Mutant::Isolation
- Object
- Mutant::Isolation
- Mutant::Isolation::Fork
- Includes:
- Unparser::Adamantium
- Defined in:
- lib/mutant/isolation/fork.rb
Overview
This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.
Isolation via the fork(2) systemcall.
Communication between parent and child process is done via anonymous pipes.
Timeouts are initially handled relatively efficiently via IO.select but once the child process pipes are on eof via busy looping on waitpid2 with Process::WNOHANG set.
Handling timeouts this way is not the conceptually most efficient solution. But its cross platform.
Design constraints:
-
Support Linux
-
Support MacOSX
-
Avoid platform specific APIs and code.
-
Only use ruby corelib.
-
Do not use any named resource.
-
Never block on latency inducing systemcall without a timeout.
-
Child process freezing before closing the pipes needs to be detected by parent process.
-
Child process freezing after closing the pipes needs to be detected by parent process.
Defined Under Namespace
Constant Summary collapse
- READ_SIZE =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
4096
- ATTRIBUTES =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
%i[block deadline log_pipe result_pipe world].freeze
Instance Method Summary collapse
-
#call(timeout, &block) ⇒ Result
private
Call block in isolation.
Instance Method Details
#call(timeout, &block) ⇒ Result
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Call block in isolation
rubocop:disable Metrics/MethodLength
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/mutant/isolation/fork.rb', line 233 def call(timeout, &block) deadline = world.deadline(timeout) io = world.io Pipe.with(io) do |result| Pipe.with(io) do |log| Parent.call( block:, deadline:, log_pipe: log, result_pipe: result, world: ) end end end |