Class: Capybara::Simulated::WorkerRuntime

Inherits:
Object
  • Object
show all
Defined in:
lib/capybara/simulated/worker_runtime.rb

Overview

Engine-uniform adapter Browser#run_worker drives. Each engine class (V8Runtime, QuickJSRuntime) has a build_worker class method that constructs the engine-specific Context/VM and wires it through these callbacks. Worker thread doesn't care which engine it's running on; it just calls eval_void / call / drain_microtasks / drain_timers / has_ready_timer? / terminate / dispose.

Instance Method Summary collapse

Constructor Details

#initialize(eval_void_fn:, call_fn:, drain_microtasks:, drain_timers:, has_ready_timer:, dispose:, terminate: nil, eval_module_graph: nil) ⇒ WorkerRuntime

Returns a new instance of WorkerRuntime.



13
14
15
16
17
18
19
20
21
22
# File 'lib/capybara/simulated/worker_runtime.rb', line 13

def initialize(eval_void_fn:, call_fn:, drain_microtasks:, drain_timers:, has_ready_timer:, dispose:, terminate: nil, eval_module_graph: nil)
  @eval_void         = eval_void_fn
  @call              = call_fn
  @drain_microtasks  = drain_microtasks
  @drain_timers      = drain_timers
  @has_ready_timer   = has_ready_timer
  @dispose           = dispose
  @terminate         = terminate
  @eval_module_graph = eval_module_graph
end

Instance Method Details

#call(name, *args) ⇒ Object



25
# File 'lib/capybara/simulated/worker_runtime.rb', line 25

def call(name, *args)          = @call.call(name, *args)

#disposeObject



29
30
31
32
33
34
# File 'lib/capybara/simulated/worker_runtime.rb', line 29

def dispose                    = @dispose.call
# Stop whatever JavaScript this worker is running, FROM ANOTHER THREAD — the one thing the
# main thread can do to a worker that is inside a call, where the `:terminate` inbox message
# cannot reach it and `Thread#kill` does not land (see `Browser#stop_worker_js`). The call in
# flight ends as a terminated call; the worker's own loop then unwinds and disposes.
# `nil` on an engine with nothing to hand back — QuickJS — where this is a no-op.

#drain_microtasksObject



26
# File 'lib/capybara/simulated/worker_runtime.rb', line 26

def drain_microtasks           = @drain_microtasks.call

#drain_timersObject



27
# File 'lib/capybara/simulated/worker_runtime.rb', line 27

def drain_timers               = @drain_timers.call

#eval_module_graph(src, url, fetch_import) ⇒ Object



50
# File 'lib/capybara/simulated/worker_runtime.rb', line 50

def eval_module_graph(src, url, fetch_import) = @eval_module_graph.call(src, url, fetch_import)

#eval_void(src) ⇒ Object



24
# File 'lib/capybara/simulated/worker_runtime.rb', line 24

def eval_void(src)             = @eval_void.call(src)

#has_ready_timer?Boolean

Returns:

  • (Boolean)


28
# File 'lib/capybara/simulated/worker_runtime.rb', line 28

def has_ready_timer?           = @has_ready_timer.call

#module_graph?Boolean

Native ES-module evaluation of a worker MAIN script + its static import graph (a {type: 'module'} service worker). fetch_import is called on the worker's own thread for each resolved static import URL and returns the script source (raising fails the evaluation — an import that 404s or has a non-JS MIME type fails the module script, and with it the Run Service Worker job). nil on engines without a native module API (QuickJS) — the caller falls back to the classic-eval path.

Returns:

  • (Boolean)


49
# File 'lib/capybara/simulated/worker_runtime.rb', line 49

def module_graph?                             = !@eval_module_graph.nil?

#terminable?Boolean

Can this engine stop a call from ANOTHER thread at all? V8 can; QuickJS cannot. The boundary asks, because the answer changes what it should do next: where there is nothing to terminate, waiting for a terminate to work is pure delay and Thread#kill — which does land on that engine — is the right escalation.

Returns:

  • (Boolean)


40
# File 'lib/capybara/simulated/worker_runtime.rb', line 40

def terminable?                = !@terminate.nil?

#terminateObject

Stop whatever JavaScript this worker is running, FROM ANOTHER THREAD — the one thing the main thread can do to a worker that is inside a call, where the :terminate inbox message cannot reach it and Thread#kill does not land (see Browser#stop_worker_js). The call in flight ends as a terminated call; the worker's own loop then unwinds and disposes. nil on an engine with nothing to hand back — QuickJS — where this is a no-op.



35
36
37
38
39
# File 'lib/capybara/simulated/worker_runtime.rb', line 35

def terminate                  = @terminate&.call
# Can this engine stop a call from ANOTHER thread at all? V8 can; QuickJS cannot. The
# boundary asks, because the answer changes what it should do next: where there is nothing
# to terminate, waiting for a terminate to work is pure delay and `Thread#kill` — which does
# land on that engine — is the right escalation.