Module: RactorRailsShim::AppShareabilizer

Defined in:
lib/ractor_rails_shim/roles/app_shareabilizer.rb

Class Method Summary collapse

Class Method Details

.apply_shareable_constantsObject



97
98
99
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 97

def self.apply_shareable_constants
  @apply_shareable_constants || RactorRailsShim::ConstantShareabilizer.method(:apply!)
end

.build_shareable_fallbackObject



145
146
147
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 145

def self.build_shareable_fallback
  @build_shareable_fallback || RactorRailsShim::FallbackBuilder.method(:build!)
end

.configure(apply_shareable_constants: nil, install_all_framework_patches: nil, precompute_lazy_ivars: nil, precompute_propshaft: nil, generate_ar_attribute_methods: nil, warm_attribute_method_patterns: nil, freeze_declared_callbacks: nil, freeze_shareable_class_ivars: nil, warm_journey_routes: nil, neutralize_logger_io: nil, replace_unshareable_procs: nil, replace_locks_and_concurrent_maps: nil, build_shareable_fallback: nil, make_shareable_fn: nil, reassign_shareable_const: nil) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 54

def self.configure(apply_shareable_constants: nil, install_all_framework_patches: nil,
                   precompute_lazy_ivars: nil, precompute_propshaft: nil,
                   generate_ar_attribute_methods: nil, warm_attribute_method_patterns: nil,
                   freeze_declared_callbacks: nil, freeze_shareable_class_ivars: nil,
                   warm_journey_routes: nil, neutralize_logger_io: nil,
                   replace_unshareable_procs: nil, replace_locks_and_concurrent_maps: nil,
                   build_shareable_fallback: nil, make_shareable_fn: nil,
                   reassign_shareable_const: nil)
  @apply_shareable_constants = apply_shareable_constants
  @install_all_framework_patches = install_all_framework_patches
  @precompute_lazy_ivars = precompute_lazy_ivars
  @precompute_propshaft = precompute_propshaft
  @generate_ar_attribute_methods = generate_ar_attribute_methods
  @warm_attribute_method_patterns = warm_attribute_method_patterns
  @freeze_declared_callbacks = freeze_declared_callbacks
  @freeze_shareable_class_ivars = freeze_shareable_class_ivars
  @warm_journey_routes = warm_journey_routes
  @neutralize_logger_io = neutralize_logger_io
  @replace_unshareable_procs = replace_unshareable_procs
  @replace_locks_and_concurrent_maps = replace_locks_and_concurrent_maps
  @build_shareable_fallback = build_shareable_fallback
  @make_shareable_fn = make_shareable_fn
  @reassign_shareable_const = reassign_shareable_const
end

.freeze_declared_callbacksObject



121
122
123
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 121

def self.freeze_declared_callbacks
  @freeze_declared_callbacks || RactorRailsShim::CallbackCapture.method(:freeze_declared_callbacks!)
end

.freeze_shareable_class_ivarsObject



125
126
127
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 125

def self.freeze_shareable_class_ivars
  @freeze_shareable_class_ivars || RactorRailsShim::Freezers::ShareableClassIvarFreezer.method(:call)
end

.generate_ar_attribute_methodsObject



113
114
115
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 113

def self.generate_ar_attribute_methods
  @generate_ar_attribute_methods || RactorRailsShim::ShareabilityTraversal.method(:generate_ar_attribute_methods!)
end

.install_all_framework_patchesObject



101
102
103
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 101

def self.install_all_framework_patches
  @install_all_framework_patches || RactorRailsShim::Installer.method(:dispatch_all_framework_patches)
end

.make_shareable!(app) ⇒ Object

Make the app Ractor-shareable. App is mutated in place (frozen). Returns the same (now-frozen) app — Ruby freeze-style. Callers must not assume a new object.



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 160

def self.make_shareable!(app)
  apply_shareable_constants.call unless RactorRailsShim::ConstantShareabilizer.applied?
  install_all_framework_patches.call
  precompute_lazy_ivars.call(app)
  precompute_propshaft.call(app)
  generate_ar_attribute_methods.call
  # Fix ActiveStorage::Blob's :metadata attribute type AFTER
  # generate_ar_attribute_methods! (which calls load_schema and rebuilds
  # _default_attributes with the wrong Type::Text for :metadata). This
  # must run BEFORE make_shareable freezes the graph, so workers see the
  # correct Type::Serialized. Runs in main only.
  RactorRailsShim.__send__(:_fix_blob_metadata_type!) if RactorRailsShim.respond_to?(:_fix_blob_metadata_type!, true) && Ractor.main?
  # Rebuild the per-model shareable snapshots (primary keys +
  # pending-attribute-modifications) AFTER eager-load, when
  # ActiveRecord::Base.descendants actually contains the app's models.
  # The initial install-time pass only captured ActiveRecord::Base, so
  # without this, worker Ractors see a nil primary_key -> `id`/to_param
  # return nil and URL helpers / record inspection break.
  RactorRailsShim._rebuild_activerecord_model_snapshots! if Ractor.main?
  warm_attribute_method_patterns.call
  freeze_declared_callbacks.call
  freeze_shareable_class_ivars.call
  warm_journey_routes.call
  neutralize_logger_io.call(app)
  replace_unshareable_procs.call(app)
  replace_locks_and_concurrent_maps.call(app)
  make_shareable_fn.call(app)
  stash!(app)
  build_shareable_fallback.call
  app
end

.make_shareable_fnObject



149
150
151
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 149

def self.make_shareable_fn
  @make_shareable_fn || Ractor.method(:make_shareable)
end

.neutralize_logger_ioObject



133
134
135
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 133

def self.neutralize_logger_io
  @neutralize_logger_io || RactorRailsShim::LoggerIONeutralizer.method(:call)
end

.precompute_lazy_ivarsObject



105
106
107
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 105

def self.precompute_lazy_ivars
  @precompute_lazy_ivars || RactorRailsShim::ShareabilityTraversal.method(:precompute_lazy_ivars)
end

.precompute_propshaftObject



109
110
111
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 109

def self.precompute_propshaft
  @precompute_propshaft || RactorRailsShim.method(:_precompute_propshaft!)
end

.reassign_shareable_constObject



153
154
155
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 153

def self.reassign_shareable_const
  @reassign_shareable_const || RactorRailsShim.method(:_reassign_shareable_const)
end

.replace_locks_and_concurrent_mapsObject



141
142
143
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 141

def self.replace_locks_and_concurrent_maps
  @replace_locks_and_concurrent_maps || RactorRailsShim::ShareabilityTraversal.method(:replace_locks_and_concurrent_maps!)
end

.replace_unshareable_procsObject



137
138
139
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 137

def self.replace_unshareable_procs
  @replace_unshareable_procs || RactorRailsShim::ShareabilityTraversal.method(:replace_unshareable_procs!)
end

.reset_configurationObject



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 79

def self.reset_configuration
  @apply_shareable_constants = nil
  @install_all_framework_patches = nil
  @precompute_lazy_ivars = nil
  @precompute_propshaft = nil
  @generate_ar_attribute_methods = nil
  @warm_attribute_method_patterns = nil
  @freeze_declared_callbacks = nil
  @freeze_shareable_class_ivars = nil
  @warm_journey_routes = nil
  @neutralize_logger_io = nil
  @replace_unshareable_procs = nil
  @replace_locks_and_concurrent_maps = nil
  @build_shareable_fallback = nil
  @make_shareable_fn = nil
  @reassign_shareable_const = nil
end

.reset_stashed!Object



215
216
217
218
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 215

def self.reset_stashed!
  @stashed = false
  remove_const(:SHAREABLE_APP) if const_defined?(:SHAREABLE_APP, false)
end

.stash!(app) ⇒ Object

One-shot stash of the app as SHAREABLE_APP on this role module. Idempotent: first call wins (via const_defined? guard). Main-Ractor- only by contract — workers must not reassign the constant. Returns the app. Issue #36b: the constant lives on AppShareabilizer, not the facade; the reassign_shareable_const seam is bypassed because it writes to the facade, not the role.



198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 198

def self.stash!(app)
  return app if const_defined?(:SHAREABLE_APP, false)
  return app unless Ractor.main?
  verbose, $VERBOSE = $VERBOSE, nil
  begin
    const_set(:SHAREABLE_APP, app)
  ensure
    $VERBOSE = verbose
  end
  @stashed = true
  app
end

.stashed?Boolean

Returns:

  • (Boolean)


211
212
213
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 211

def self.stashed?
  @stashed
end

.warm_attribute_method_patternsObject



117
118
119
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 117

def self.warm_attribute_method_patterns
  @warm_attribute_method_patterns || RactorRailsShim::ShareabilityTraversal.method(:warm_attribute_method_patterns!)
end

.warm_journey_routesObject



129
130
131
# File 'lib/ractor_rails_shim/roles/app_shareabilizer.rb', line 129

def self.warm_journey_routes
  @warm_journey_routes || RactorRailsShim.method(:_warm_journey_routes!)
end