ractor-rails-shim 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +101 -0
- data/LICENSE.txt +21 -0
- data/README.md +265 -0
- data/exe/ractor-rails-check +39 -0
- data/lib/ractor_rails_shim/check.rb +190 -0
- data/lib/ractor_rails_shim/fallback_ies.rb +33 -0
- data/lib/ractor_rails_shim/patches/action_controller.rb +301 -0
- data/lib/ractor_rails_shim/patches/action_dispatch.rb +851 -0
- data/lib/ractor_rails_shim/patches/action_view.rb +582 -0
- data/lib/ractor_rails_shim/patches/active_model_attribute.rb +97 -0
- data/lib/ractor_rails_shim/patches/active_record_model_schema.rb +58 -0
- data/lib/ractor_rails_shim/patches/active_support.rb +1085 -0
- data/lib/ractor_rails_shim/patches/activerecord.rb +1727 -0
- data/lib/ractor_rails_shim/patches/class_attribute.rb +194 -0
- data/lib/ractor_rails_shim/patches/core.rb +806 -0
- data/lib/ractor_rails_shim/patches/devise.rb +172 -0
- data/lib/ractor_rails_shim/patches/execution_wrapper.rb +76 -0
- data/lib/ractor_rails_shim/patches/kaminari.rb +82 -0
- data/lib/ractor_rails_shim/patches/make_shareable.rb +853 -0
- data/lib/ractor_rails_shim/patches/mattr_accessor.rb +162 -0
- data/lib/ractor_rails_shim/patches/openssl.rb +58 -0
- data/lib/ractor_rails_shim/patches/orm_adapter.rb +32 -0
- data/lib/ractor_rails_shim/patches/polymorphic_routes.rb +115 -0
- data/lib/ractor_rails_shim/patches/propshaft.rb +110 -0
- data/lib/ractor_rails_shim/patches/rack.rb +160 -0
- data/lib/ractor_rails_shim/patches/rails_module.rb +192 -0
- data/lib/ractor_rails_shim/patches/route_helpers.rb +119 -0
- data/lib/ractor_rails_shim/patches/rubygems.rb +65 -0
- data/lib/ractor_rails_shim/patches/url_helpers.rb +78 -0
- data/lib/ractor_rails_shim/patches/warden.rb +195 -0
- data/lib/ractor_rails_shim/patches/zeitwerk_registry.rb +124 -0
- data/lib/ractor_rails_shim/patches.rb +67 -0
- data/lib/ractor_rails_shim/version.rb +5 -0
- data/lib/ractor_rails_shim/version_check.rb +88 -0
- data/lib/ractor_rails_shim.rb +33 -0
- metadata +104 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Patch Zeitwerk::Registry to route its class ivars (@loaders, @mutex,
|
|
4
|
+
# @gem_loaders_by_root_file, @autoloads, @explicit_namespaces, @inceptions)
|
|
5
|
+
# through IsolatedExecutionState. Zeitwerk uses raw class ivars (not
|
|
6
|
+
# mattr_accessor), so the shim's macro rewrite doesn't catch them. Each
|
|
7
|
+
# Ractor that boots a Rails app gets its own registry state (its own
|
|
8
|
+
# loaders list, its own mutex, its own autoloads map), which is correct
|
|
9
|
+
# for per-Ractor boot: each worker's autoloaders are independent.
|
|
10
|
+
#
|
|
11
|
+
# The defaults are the same classes Zeitwerk instantiates at module-load
|
|
12
|
+
# time (Loaders, Hash, Autoloads, ExplicitNamespaces, Inceptions, Mutex).
|
|
13
|
+
# Workers lazily build their own on first read.
|
|
14
|
+
|
|
15
|
+
module RactorRailsShim
|
|
16
|
+
class << self
|
|
17
|
+
def install_zeitwerk_registry
|
|
18
|
+
return if @zeitwerk_patched
|
|
19
|
+
@zeitwerk_patched = true
|
|
20
|
+
_register_patch :zeitwerk_registry, "8.1"
|
|
21
|
+
if defined?(::Zeitwerk::Registry)
|
|
22
|
+
patch_zeitwerk_registry!
|
|
23
|
+
else
|
|
24
|
+
# Defer until Zeitwerk loads. A TracePoint(:class) fires when
|
|
25
|
+
# `module Registry` opens. One-shot.
|
|
26
|
+
@zw_tp = TracePoint.new(:class) do |trace|
|
|
27
|
+
if defined?(::Zeitwerk::Registry) && !@zeitwerk_registry_patched
|
|
28
|
+
@zw_tp.disable
|
|
29
|
+
patch_zeitwerk_registry!
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
@zw_tp.enable
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def patch_zeitwerk_registry!
|
|
37
|
+
return if @zeitwerk_registry_patched
|
|
38
|
+
@zeitwerk_registry_patched = true
|
|
39
|
+
|
|
40
|
+
reg = ::Zeitwerk::Registry
|
|
41
|
+
# The ivars Zeitwerk sets at the bottom of registry.rb. Map each to an
|
|
42
|
+
# IES key and a default-builder string (eval'd in the reader when the
|
|
43
|
+
# Ractor's slot is empty). Builders reference Zeitwerk constants by
|
|
44
|
+
# full path so they're resolvable from any Ractor.
|
|
45
|
+
ivars = {
|
|
46
|
+
loaders: [:ractor_rails_shim_zw_loaders, "Zeitwerk::Registry::Loaders.new"],
|
|
47
|
+
gem_loaders_by_root_file: [:ractor_rails_shim_zw_gem, "{}"],
|
|
48
|
+
autoloads: [:ractor_rails_shim_zw_autoloads, "Zeitwerk::Registry::Autoloads.new"],
|
|
49
|
+
explicit_namespaces: [:ractor_rails_shim_zw_explicit, "Zeitwerk::Registry::ExplicitNamespaces.new"],
|
|
50
|
+
inceptions: [:ractor_rails_shim_zw_inceptions, "Zeitwerk::Registry::Inceptions.new"],
|
|
51
|
+
mutex: [:ractor_rails_shim_zw_mutex, "Mutex.new"],
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Redefine each reader (and the mutex, which is read directly as @mutex)
|
|
55
|
+
# to route through IES with lazy per-Ractor init. Use a PREPENDED module
|
|
56
|
+
# (not direct module_eval on the singleton class) because Zeitwerk's
|
|
57
|
+
# `attr_reader :loaders` etc. run LATER in the module body and would
|
|
58
|
+
# clobber a direct redefinition — same load-order issue as the Rails
|
|
59
|
+
# module accessors. A prepended module stays in front of the lookup chain.
|
|
60
|
+
#
|
|
61
|
+
# In the MAIN ractor, fall back to the existing ivar (set by Zeitwerk at
|
|
62
|
+
# the bottom of registry.rb) so main-ractor state is preserved. Worker
|
|
63
|
+
# ractors lazily build their own via the builder string.
|
|
64
|
+
reader_patch = Module.new
|
|
65
|
+
ivars.each do |ivar, (key, builder)|
|
|
66
|
+
key_str = key.inspect
|
|
67
|
+
ivar_sym = :"@#{ivar}"
|
|
68
|
+
ivar_str = ivar_sym.inspect
|
|
69
|
+
reader_patch.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
70
|
+
def #{ivar}
|
|
71
|
+
v = ActiveSupport::IsolatedExecutionState[#{key_str}]
|
|
72
|
+
return v unless v.nil?
|
|
73
|
+
if Ractor.main?
|
|
74
|
+
existing = instance_variable_get(#{ivar_str}) if instance_variable_defined?(#{ivar_str})
|
|
75
|
+
if existing
|
|
76
|
+
ActiveSupport::IsolatedExecutionState[#{key_str}] = existing
|
|
77
|
+
return existing
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
v = #{builder}
|
|
81
|
+
ActiveSupport::IsolatedExecutionState[#{key_str}] = v
|
|
82
|
+
v
|
|
83
|
+
end
|
|
84
|
+
RUBY
|
|
85
|
+
end
|
|
86
|
+
reg.singleton_class.prepend(reader_patch)
|
|
87
|
+
|
|
88
|
+
# `conflicting_root_dir?` and `loader_for_gem` read @mutex / @gem_loaders
|
|
89
|
+
# directly via instance_variable_get-ish access (they use @mutex in the
|
|
90
|
+
# method body). Since we redefined the readers, the direct @mutex refs
|
|
91
|
+
# in those methods still hit the ivar. We need to rewrite those two
|
|
92
|
+
# methods to call the reader instead. Easiest: prepend a module that
|
|
93
|
+
# calls self.mutex / self.gem_loaders_by_root_file.
|
|
94
|
+
reg.singleton_class.prepend(Module.new {
|
|
95
|
+
def conflicting_root_dir?(loader, new_root_dir)
|
|
96
|
+
mutex.synchronize do
|
|
97
|
+
loaders.each do |existing_loader|
|
|
98
|
+
next if existing_loader == loader
|
|
99
|
+
existing_loader.__roots.each_key do |existing_root_dir|
|
|
100
|
+
next if !new_root_dir.start_with?(existing_root_dir) && !existing_root_dir.start_with?(new_root_dir)
|
|
101
|
+
new_root_dir_slash = new_root_dir + '/'
|
|
102
|
+
existing_root_dir_slash = existing_root_dir + '/'
|
|
103
|
+
next if !new_root_dir_slash.start_with?(existing_root_dir_slash) && !existing_root_dir_slash.start_with?(new_root_dir_slash)
|
|
104
|
+
next if loader.__ignores?(existing_root_dir)
|
|
105
|
+
break if existing_loader.__ignores?(new_root_dir)
|
|
106
|
+
return existing_loader
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
nil
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def loader_for_gem(root_file, namespace:, warn_on_extra_files:)
|
|
114
|
+
h = gem_loaders_by_root_file
|
|
115
|
+
h[root_file] ||= Zeitwerk::GemLoader.__new(root_file, namespace: namespace, warn_on_extra_files: warn_on_extra_files)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def unregister_loader(loader)
|
|
119
|
+
gem_loaders_by_root_file.delete_if { |_, l| l == loader }
|
|
120
|
+
end
|
|
121
|
+
})
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# The core shim: reroute Rails' class-level instance variable accessors
|
|
4
|
+
# through Ractor-safe storage.
|
|
5
|
+
#
|
|
6
|
+
# Background: Rails stores global state in class ivars:
|
|
7
|
+
#
|
|
8
|
+
# class Rails
|
|
9
|
+
# class << self
|
|
10
|
+
# attr_accessor :app_class, :cache, :logger
|
|
11
|
+
# def application; @application ||= ...; end
|
|
12
|
+
# end
|
|
13
|
+
# end
|
|
14
|
+
#
|
|
15
|
+
# From a non-main Ractor these reads/writes raise Ractor::IsolationError:
|
|
16
|
+
# "can not get unshareable values from instance variables of classes/modules
|
|
17
|
+
# from non-main Ractors"
|
|
18
|
+
#
|
|
19
|
+
# The fix: store the values in ActiveSupport::IsolatedExecutionState, which
|
|
20
|
+
# is already Ractor-safe. It's thread-local storage (Thread.current[:key]),
|
|
21
|
+
# and each Ractor has its own threads, so each Ractor gets its own slot.
|
|
22
|
+
# Verified on Ruby 4.0.5: a non-main Ractor reads nil for a key the main
|
|
23
|
+
# Ractor set, sets its own value without error, and main's value is intact.
|
|
24
|
+
#
|
|
25
|
+
# IMPORTANT: all method redefinitions use module_eval with STRING, not
|
|
26
|
+
# define_method with a block. A block captures the defining Ractor's
|
|
27
|
+
# binding, and calling it from another Ractor raises:
|
|
28
|
+
# "defined with an un-shareable Proc in a different Ractor"
|
|
29
|
+
# String eval produces methods with no captured binding, callable from any
|
|
30
|
+
# Ractor. Verified on Ruby 4.0.5.
|
|
31
|
+
|
|
32
|
+
begin
|
|
33
|
+
require "active_support/isolated_execution_state"
|
|
34
|
+
rescue LoadError
|
|
35
|
+
# ActiveSupport not installed — the fallback below provides the same API.
|
|
36
|
+
end
|
|
37
|
+
require_relative "fallback_ies"
|
|
38
|
+
require_relative "version_check"
|
|
39
|
+
|
|
40
|
+
# Per-concern patch files. Each reopens RactorRailsShim's singleton class
|
|
41
|
+
# to add its `_install_*` method(s). The order matters only for constants
|
|
42
|
+
# (core.rb defines the module skeleton + constants that others reference).
|
|
43
|
+
require_relative "patches/core"
|
|
44
|
+
require_relative "patches/make_shareable"
|
|
45
|
+
require_relative "patches/rails_module"
|
|
46
|
+
require_relative "patches/mattr_accessor"
|
|
47
|
+
require_relative "patches/class_attribute"
|
|
48
|
+
require_relative "patches/zeitwerk_registry"
|
|
49
|
+
require_relative "patches/route_helpers"
|
|
50
|
+
require_relative "patches/url_helpers"
|
|
51
|
+
require_relative "patches/execution_wrapper"
|
|
52
|
+
require_relative "patches/rack"
|
|
53
|
+
require_relative "patches/action_view"
|
|
54
|
+
require_relative "patches/action_controller"
|
|
55
|
+
require_relative "patches/action_dispatch"
|
|
56
|
+
require_relative "patches/polymorphic_routes"
|
|
57
|
+
require_relative "patches/active_support"
|
|
58
|
+
require_relative "patches/warden"
|
|
59
|
+
require_relative "patches/active_model_attribute"
|
|
60
|
+
require_relative "patches/active_record_model_schema"
|
|
61
|
+
require_relative "patches/activerecord"
|
|
62
|
+
require_relative "patches/kaminari"
|
|
63
|
+
require_relative "patches/propshaft"
|
|
64
|
+
require_relative "patches/devise"
|
|
65
|
+
require_relative "patches/orm_adapter"
|
|
66
|
+
require_relative "patches/openssl"
|
|
67
|
+
require_relative "patches/rubygems"
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Version detection and gating for ractor-rails-shim.
|
|
4
|
+
#
|
|
5
|
+
# The shim's patches target specific Rails class layouts (class_attribute,
|
|
6
|
+
# Callbacks, PathRegistry, LookupContext, …) and Ruby Ractor semantics that
|
|
7
|
+
# change between releases. Applying an 8.1-targeted patch to a 7.1 app would
|
|
8
|
+
# silently miss blockers or redefine the wrong methods. This module makes the
|
|
9
|
+
# version checks robust (Gem::Version, not string prefix comparison) and gives
|
|
10
|
+
# each patch a tested-versions tag so the dispatcher can apply only patches
|
|
11
|
+
# that match the runtime.
|
|
12
|
+
#
|
|
13
|
+
# Three concerns live here:
|
|
14
|
+
#
|
|
15
|
+
# 1. Reading the runtime versions (Ruby + Rails) defensively — Rails may not
|
|
16
|
+
# be loaded yet at install time.
|
|
17
|
+
# 2. A policy switch for mismatches: :warn (default, backward compatible),
|
|
18
|
+
# :strict (raise), or :off (silent). Set via
|
|
19
|
+
# `RactorRailsShim.version_policy = :strict`.
|
|
20
|
+
# 3. A registry (`PATCH_VERSIONS`) mapping each install_* patch name to the
|
|
21
|
+
# Rails versions it was developed and tested against, plus reporters
|
|
22
|
+
# (`applicable_patches` / `skipped_patches`) so users (and CI) can see
|
|
23
|
+
# exactly what applied to their runtime.
|
|
24
|
+
module RactorRailsShim
|
|
25
|
+
module Version
|
|
26
|
+
# Ruby version the shim was developed against (major.minor). Ractor
|
|
27
|
+
# semantics are still settling; non-4.0 Rubies may behave differently.
|
|
28
|
+
SUPPORTED_RUBY = "4.0"
|
|
29
|
+
# Rails versions each patch was tested against. Patches are registered
|
|
30
|
+
# with one or more entries from this list; the dispatcher applies a patch
|
|
31
|
+
# only if the runtime Rails version matches one of its tags. To add 7.x
|
|
32
|
+
# support, write the version-specific patch variants and add the tag here.
|
|
33
|
+
TESTED_RAILS = ["8.1"].freeze
|
|
34
|
+
|
|
35
|
+
class << self
|
|
36
|
+
# Runtime Ruby version as a Gem::Version (e.g. "4.0.5"). Always
|
|
37
|
+
# available — Ruby is obviously loaded.
|
|
38
|
+
def ruby
|
|
39
|
+
Gem::Version.new(RUBY_VERSION)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Runtime Rails version as a Gem::Version, or nil if Rails isn't
|
|
43
|
+
# loaded yet (the normal config/boot.rb case — install is called before
|
|
44
|
+
# `require "rails"`).
|
|
45
|
+
def rails
|
|
46
|
+
return nil unless defined?(::Rails) && defined?(::Rails::VERSION)
|
|
47
|
+
return nil if ::Rails::VERSION::STRING.nil? || ::Rails::VERSION::STRING.empty?
|
|
48
|
+
begin
|
|
49
|
+
Gem::Version.new(::Rails::VERSION::STRING)
|
|
50
|
+
rescue ArgumentError
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Major.minor segment as a String ("8.1"), or nil if Rails isn't loaded.
|
|
56
|
+
def rails_segment
|
|
57
|
+
return nil unless (rv = rails)
|
|
58
|
+
"#{rv.segments[0]}.#{rv.segments[1]}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Major.minor segment of the running Ruby.
|
|
62
|
+
def ruby_segment
|
|
63
|
+
v = ruby
|
|
64
|
+
"#{v.segments[0]}.#{v.segments[1]}"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# True if the runtime Ruby's major.minor matches the supported segment.
|
|
68
|
+
def supported_ruby?
|
|
69
|
+
ruby_segment == SUPPORTED_RUBY
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# True if the runtime Rails major.minor is in the tested set (or Rails
|
|
73
|
+
# isn't loaded yet — can't decide, so optimistic).
|
|
74
|
+
def supported_rails?
|
|
75
|
+
return true unless rails # Rails not loaded: defer decision.
|
|
76
|
+
TESTED_RAILS.include?(rails_segment)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Compare a runtime segment ("8.1") against a Gem::Requirement string
|
|
80
|
+
# (e.g. ">= 7.0", "~> 8.1"). Returns true if the segment satisfies the
|
|
81
|
+
# requirement. Used by the patch registry to decide applicability.
|
|
82
|
+
def satisfies?(segment, requirement)
|
|
83
|
+
return false if segment.nil?
|
|
84
|
+
Gem::Requirement.new(requirement).satisfied_by?(Gem::Version.new(segment))
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "ractor_rails_shim/version"
|
|
4
|
+
require_relative "ractor_rails_shim/patches"
|
|
5
|
+
require_relative "ractor_rails_shim/check"
|
|
6
|
+
|
|
7
|
+
# A monkey-patch shim that reroutes Rails' class-level instance variable
|
|
8
|
+
# accessors (Rails.application, Rails.cache, Rails.logger, mattr_accessor,
|
|
9
|
+
# etc.) through ActiveSupport::IsolatedExecutionState, which is
|
|
10
|
+
# Ractor-safe (thread-local; each Ractor has its own threads).
|
|
11
|
+
#
|
|
12
|
+
# This lets a Rails app run in Ractor mode without forking Rails itself.
|
|
13
|
+
# Each Ractor gets its own copy of the globals (same shape as forking one
|
|
14
|
+
# process per core, but without heap duplication). For shareable state
|
|
15
|
+
# (frozen config, route tables) use Ractor.make_shareable + a constant
|
|
16
|
+
# instead — that shares one copy by reference, zero copy.
|
|
17
|
+
#
|
|
18
|
+
# Stopgap: the goal is for Rails to do this upstream. When it does, this
|
|
19
|
+
# shim becomes a no-op and can be removed from your Gemfile.
|
|
20
|
+
module RactorRailsShim
|
|
21
|
+
class << self
|
|
22
|
+
# Require this gem and the patches auto-install IF Rails is loaded.
|
|
23
|
+
# If Rails isn't loaded yet, install is deferred to the first call
|
|
24
|
+
# of `install` (call it from config/boot.rb before Rails.application).
|
|
25
|
+
def autoload_install!
|
|
26
|
+
install if defined?(::Rails) && !installed?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Auto-install if Rails is already loaded (e.g. via Bundler.require in a
|
|
32
|
+
# console). If not, the user calls RactorRailsShim.install from boot.
|
|
33
|
+
RactorRailsShim.autoload_install!
|
metadata
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ractor-rails-shim
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- dev
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: activesupport
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
description: |
|
|
27
|
+
Rails stores global state (Rails.application, Rails.cache, Rails.logger,
|
|
28
|
+
config set via mattr_accessor) in class-level instance variables, which
|
|
29
|
+
are illegal to read or write from non-main Ractors. This shim reroutes
|
|
30
|
+
those accessors through ActiveSupport::IsolatedExecutionState (which is
|
|
31
|
+
already Ractor-safe, being thread-local with per-ractor threads) or
|
|
32
|
+
Ractor.store_if_absent, so a Rails app can run in Ractor mode.
|
|
33
|
+
|
|
34
|
+
This is a stopgap: the goal is for Rails to do this upstream, at which
|
|
35
|
+
point the shim becomes a no-op and can be removed.
|
|
36
|
+
email:
|
|
37
|
+
- kachur.daniil@gmail.com
|
|
38
|
+
executables:
|
|
39
|
+
- ractor-rails-check
|
|
40
|
+
extensions: []
|
|
41
|
+
extra_rdoc_files: []
|
|
42
|
+
files:
|
|
43
|
+
- CHANGELOG.md
|
|
44
|
+
- LICENSE.txt
|
|
45
|
+
- README.md
|
|
46
|
+
- exe/ractor-rails-check
|
|
47
|
+
- lib/ractor_rails_shim.rb
|
|
48
|
+
- lib/ractor_rails_shim/check.rb
|
|
49
|
+
- lib/ractor_rails_shim/fallback_ies.rb
|
|
50
|
+
- lib/ractor_rails_shim/patches.rb
|
|
51
|
+
- lib/ractor_rails_shim/patches/action_controller.rb
|
|
52
|
+
- lib/ractor_rails_shim/patches/action_dispatch.rb
|
|
53
|
+
- lib/ractor_rails_shim/patches/action_view.rb
|
|
54
|
+
- lib/ractor_rails_shim/patches/active_model_attribute.rb
|
|
55
|
+
- lib/ractor_rails_shim/patches/active_record_model_schema.rb
|
|
56
|
+
- lib/ractor_rails_shim/patches/active_support.rb
|
|
57
|
+
- lib/ractor_rails_shim/patches/activerecord.rb
|
|
58
|
+
- lib/ractor_rails_shim/patches/class_attribute.rb
|
|
59
|
+
- lib/ractor_rails_shim/patches/core.rb
|
|
60
|
+
- lib/ractor_rails_shim/patches/devise.rb
|
|
61
|
+
- lib/ractor_rails_shim/patches/execution_wrapper.rb
|
|
62
|
+
- lib/ractor_rails_shim/patches/kaminari.rb
|
|
63
|
+
- lib/ractor_rails_shim/patches/make_shareable.rb
|
|
64
|
+
- lib/ractor_rails_shim/patches/mattr_accessor.rb
|
|
65
|
+
- lib/ractor_rails_shim/patches/openssl.rb
|
|
66
|
+
- lib/ractor_rails_shim/patches/orm_adapter.rb
|
|
67
|
+
- lib/ractor_rails_shim/patches/polymorphic_routes.rb
|
|
68
|
+
- lib/ractor_rails_shim/patches/propshaft.rb
|
|
69
|
+
- lib/ractor_rails_shim/patches/rack.rb
|
|
70
|
+
- lib/ractor_rails_shim/patches/rails_module.rb
|
|
71
|
+
- lib/ractor_rails_shim/patches/route_helpers.rb
|
|
72
|
+
- lib/ractor_rails_shim/patches/rubygems.rb
|
|
73
|
+
- lib/ractor_rails_shim/patches/url_helpers.rb
|
|
74
|
+
- lib/ractor_rails_shim/patches/warden.rb
|
|
75
|
+
- lib/ractor_rails_shim/patches/zeitwerk_registry.rb
|
|
76
|
+
- lib/ractor_rails_shim/version.rb
|
|
77
|
+
- lib/ractor_rails_shim/version_check.rb
|
|
78
|
+
homepage: https://github.com/DDKatch/ractor-rails-shim
|
|
79
|
+
licenses:
|
|
80
|
+
- MIT
|
|
81
|
+
metadata:
|
|
82
|
+
homepage_uri: https://github.com/DDKatch/ractor-rails-shim
|
|
83
|
+
source_code_uri: https://github.com/DDKatch/ractor-rails-shim
|
|
84
|
+
changelog_uri: https://github.com/DDKatch/ractor-rails-shim/blob/main/CHANGELOG.md
|
|
85
|
+
bug_tracker_uri: https://github.com/DDKatch/ractor-rails-shim/issues
|
|
86
|
+
rubygems_mfa_required: 'true'
|
|
87
|
+
rdoc_options: []
|
|
88
|
+
require_paths:
|
|
89
|
+
- lib
|
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
91
|
+
requirements:
|
|
92
|
+
- - ">="
|
|
93
|
+
- !ruby/object:Gem::Version
|
|
94
|
+
version: '4.0'
|
|
95
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
|
+
requirements:
|
|
97
|
+
- - ">="
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '0'
|
|
100
|
+
requirements: []
|
|
101
|
+
rubygems_version: 4.0.10
|
|
102
|
+
specification_version: 4
|
|
103
|
+
summary: Monkey-patch Rails class-level globals to be Ractor-safe
|
|
104
|
+
test_files: []
|