Module: Sashiko::Box

Defined in:
lib/sashiko/box.rb

Overview

Wrapper around Ruby 4.0’s experimental Ruby::Box.

Ruby::Box creates an isolated loading namespace — requires, class definitions, monkey-patches, and OTel tracer providers loaded inside a Box are invisible to the rest of the process. That makes Box useful for multi-tenant observability inside a single Ruby process: each tenant gets its own Sashiko, its own OTel exporter, and its own instrumented classes.

Requires the process to be started with RUBY_BOX=1 (Box is opt-in and experimental in Ruby 4.0).

tenant_a = Sashiko::Box.new
tenant_a.eval(<<~RUBY)
  OpenTelemetry::SDK.configure { |c| c.service_name = "tenant-a" }
  # ... load tenant-a adapters / instrument classes ...
RUBY

If you want a bare Ruby::Box without Sashiko pre-required, use ::Ruby::Box.new directly.

Defined Under Namespace

Classes: NotEnabledError

Class Method Summary collapse

Class Method Details

.enabled?Boolean

Returns:

  • (Boolean)


32
# File 'lib/sashiko/box.rb', line 32

def enabled? = !!(defined?(::Ruby::Box) && ::Ruby::Box.enabled?)

.new(lib_path: default_lib_path) ⇒ Object

Create a new Ruby::Box with Sashiko pre-required inside it. The box can then ‘eval` user code that uses Sashiko::Traced, Sashiko::Context, etc. as if it were main-process code — except all state stays inside the box.

Raises NotEnabledError when not under RUBY_BOX=1 so callers fail fast instead of getting obscure errors.

Raises:



41
42
43
44
45
46
47
48
49
# File 'lib/sashiko/box.rb', line 41

def new(lib_path: default_lib_path)
  raise NotEnabledError unless enabled?
  box = ::Ruby::Box.new
  box.eval(<<~RUBY)
    $LOAD_PATH.unshift(#{lib_path.inspect})
    require "sashiko"
  RUBY
  box
end