Module: RactorRailsShim::Freezers::ShareableClassIvarFreezer
- Extended by:
- RoleDefaults
- Defined in:
- lib/ractor_rails_shim/roles/freezers.rb
Overview
ShareableClassIvarFreezer: walks SHAREABLE_CLASS_IVARS (class name,
ivar name pairs), reads each ivar, makes it Ractor-shareable
(deep-frozen), and writes it back so workers read the shareable
copy. Also pre-touches memoizing accessors so workers don't try to
write the ivar lazily (which would raise FrozenError on the frozen
class). Extracted from _freeze_shareable_class_ivars! in
make_shareable.rb (Issue #27, POODR §6a Modules & Roles).
Constant Summary
collapse
- PRE_TOUCH =
Mutable registry of [class_name, method_name] pairs to pre-touch
before the main shareable-class-ivar freeze. A pre-touch forces
lazy memoizing accessors to populate in the MAIN Ractor so workers
don't try to write the (now frozen) ivar on first read. Downstream
apps can register their own entries via add_pre_touch.
[
["ActiveSupport::Editor", :current],
["Warden::Strategies", :_strategies],
]
Class Method Summary
collapse
default_funnel, default_reassign_shareable_const, default_safe_const_get
Class Method Details
.add_pre_touch(class_name, method_name) ⇒ Object
311
312
313
|
# File 'lib/ractor_rails_shim/roles/freezers.rb', line 311
def self.add_pre_touch(class_name, method_name)
PRE_TOUCH << [class_name, method_name] unless PRE_TOUCH.any? { |n, m| n == class_name && m == method_name }
end
|
.call ⇒ Object
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
|
# File 'lib/ractor_rails_shim/roles/freezers.rb', line 315
def self.call
RactorRailsShim::Registry.shareable_class_ivars.each do |(class_name, ivar)|
mod = safe_const_get.call(class_name)
next unless mod && mod.instance_variable_defined?(ivar)
val = mod.instance_variable_get(ivar)
next if val.nil?
funnel.call("freeze global ivar #{class_name}#{ivar}") do
Ractor.make_shareable(val)
mod.instance_variable_set(ivar, val)
end
end
PRE_TOUCH.each do |class_name, method_name|
mod = safe_const_get.call(class_name)
next unless mod && mod.respond_to?(method_name, true)
funnel.call("pre-touch #{class_name}.#{method_name}") do
mod.send(method_name)
end
end
true
end
|
283
284
285
286
|
# File 'lib/ractor_rails_shim/roles/freezers.rb', line 283
def self.configure(funnel: nil, safe_const_get: nil)
@funnel = funnel
@safe_const_get = safe_const_get
end
|
.funnel ⇒ Object
293
294
295
|
# File 'lib/ractor_rails_shim/roles/freezers.rb', line 293
def self.funnel
@funnel || default_funnel
end
|
.reset_configuration ⇒ Object
288
289
290
291
|
# File 'lib/ractor_rails_shim/roles/freezers.rb', line 288
def self.reset_configuration
@funnel = nil
@safe_const_get = nil
end
|
.safe_const_get ⇒ Object
297
298
299
|
# File 'lib/ractor_rails_shim/roles/freezers.rb', line 297
def self.safe_const_get
@safe_const_get || default_safe_const_get
end
|