Module: Rigor::Plugin::Isolation
- Defined in:
- lib/rigor/plugin/isolation.rb
Overview
ADR-39 slice 5 — the selectable isolation strategy for target-library invocation. A plugin invokes a
pure method on a trusted target library (e.g. ActiveSupport::Inflector.pluralize("post")) through
Isolation.call; how much the invocation is isolated from Rigor's own process is a configurable strategy
(RIGOR_PLUGIN_ISOLATION env; the exe/rigor launcher maps .rigor.yml's plugins_isolation: onto it
before re-exec). Three backends behind one interface:
none— load into the main space and call directly. Lowest cost; no isolation. Used as the fallback where fork is unavailable; fine because the invoked library is trusted + pure.ruby_box— call inside a Box (Ruby::Box,RUBY_BOX=1). Isolates core-class monkey-patches + lets gem versions coexist, but a native crash in the boxed work still takes the process down (in-process).process(default) — call in a forked worker (Process); returns data over a pipe. The strongest: a child crash (evenSIGSEGV) is contained — the parent survives and declines. Higher cost (fork + IPC).
All three answer with the method's return value, or raise Unavailable (never approximate) when the target library cannot be reached in the chosen strategy — the caller's per-plugin rescue turns that into silence, never a wrong fact.
Defined Under Namespace
Modules: Direct, Process, RubyBox Classes: Unavailable
Constant Summary collapse
- STRATEGIES =
%w[none ruby_box process].freeze
- DEFAULT =
The default strategy.
process(a crash-contained forked worker) is the default: it isolates the target library's monkey-patches + crashes from Rigor with no in-process contamination, and forks a single persistent worker (not one per call). It falls back tononewhere fork is unavailable (see #backend). "process"
Class Method Summary collapse
-
.backend ⇒ Object
The backend module for the configured strategy.
-
.call(feature:, receiver:, method:, args:) ⇒ Object
Invokes
receiver.method(*args)on a target library, requiringfeaturefirst, under the configured isolation strategy. -
.strategy_name ⇒ Object
The configured strategy name (
RIGOR_PLUGIN_ISOLATION), defaulting to DEFAULT for any unset / unrecognised value.
Class Method Details
.backend ⇒ Object
The backend module for the configured strategy. process (including the default) falls back to
Direct where fork is unavailable (Windows / JRuby) so inflection still works rather than silently
degrading — the libraries are trusted + pure, so the main-space fallback is acceptable when no
fork-based isolation can be had.
58 59 60 61 62 63 64 |
# File 'lib/rigor/plugin/isolation.rb', line 58 def backend case strategy_name when "ruby_box" then RubyBox when "none" then Direct else Process.available? ? Process : Direct end end |
.call(feature:, receiver:, method:, args:) ⇒ Object
Invokes receiver.method(*args) on a target library, requiring feature first, under the configured
isolation strategy. receiver is a constant name (String), method a Symbol from the caller's
allow-list, and args simple, Marshal-able / inspectable values (Strings) — never free input. Returns
the result, or raises Unavailable.
50 51 52 |
# File 'lib/rigor/plugin/isolation.rb', line 50 def call(feature:, receiver:, method:, args:) backend.call(feature: feature, receiver: receiver, method: method, args: args) end |
.strategy_name ⇒ Object
The configured strategy name (RIGOR_PLUGIN_ISOLATION), defaulting to DEFAULT for any unset /
unrecognised value.
41 42 43 44 |
# File 'lib/rigor/plugin/isolation.rb', line 41 def strategy_name name = ENV["RIGOR_PLUGIN_ISOLATION"].to_s STRATEGIES.include?(name) ? name : DEFAULT end |