Skip to content

Commit 30363d0

Browse files
authored
Merge pull request rails#43673 from Shopify/deprecate-per-thread-registry
Eliminate internal uses of `PerThreadRegistry` and deprecate it
2 parents ffb3a3e + b4eae47 commit 30363d0

File tree

12 files changed

+101
-122
lines changed

12 files changed

+101
-122
lines changed

actionview/lib/action_view/helpers/cache_helper.rb

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -292,19 +292,20 @@ def write_fragment_for(name, options)
292292
controller.write_fragment(name, fragment, options)
293293
end
294294

295-
class CachingRegistry
296-
extend ActiveSupport::PerThreadRegistry
295+
module CachingRegistry # :nodoc:
296+
extend self
297297

298-
attr_accessor :caching
299-
alias caching? caching
298+
def caching?
299+
ActiveSupport::IsolatedExecutionState[:action_view_caching] ||= false
300+
end
300301

301-
def self.track_caching
302-
caching_was = self.caching
303-
self.caching = true
302+
def track_caching
303+
caching_was = ActiveSupport::IsolatedExecutionState[:action_view_caching]
304+
ActiveSupport::IsolatedExecutionState[:action_view_caching] = true
304305

305306
yield
306307
ensure
307-
self.caching = caching_was
308+
ActiveSupport::IsolatedExecutionState[:action_view_caching] = caching_was
308309
end
309310
end
310311
end

activerecord/lib/active_record/explain_registry.rb

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
11
# frozen_string_literal: true
22

3-
require "active_support/per_thread_registry"
3+
require "active_support/core_ext/module/delegation"
44

55
module ActiveRecord
66
# This is a thread locals registry for EXPLAIN. For example
77
#
88
# ActiveRecord::ExplainRegistry.queries
99
#
1010
# returns the collected queries local to the current thread.
11-
#
12-
# See the documentation of ActiveSupport::PerThreadRegistry
13-
# for further details.
1411
class ExplainRegistry # :nodoc:
15-
extend ActiveSupport::PerThreadRegistry
12+
class << self
13+
delegate :reset, :collect, :collect=, :collect?, :queries, to: :instance
14+
15+
private
16+
def instance
17+
ActiveSupport::IsolatedExecutionState[:active_record_explain_registry] ||= new
18+
end
19+
end
1620

17-
attr_accessor :queries, :collect
21+
attr_accessor :collect
22+
attr_reader :queries
1823

1924
def initialize
2025
reset

activerecord/lib/active_record/relation/record_fetch_warning.rb

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,15 @@ def exec_queries
3131
end
3232
# :startdoc:
3333

34-
class QueryRegistry # :nodoc:
35-
extend ActiveSupport::PerThreadRegistry
34+
module QueryRegistry # :nodoc:
35+
extend self
3636

37-
attr_reader :queries
38-
39-
def initialize
40-
@queries = []
37+
def queries
38+
ActiveSupport::IsolatedExecutionState[:active_record_query_registry] ||= []
4139
end
4240

4341
def reset
44-
@queries.clear
42+
queries.clear
4543
end
4644
end
4745
end
Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
# frozen_string_literal: true
22

3-
require "active_support/per_thread_registry"
4-
53
module ActiveRecord
64
# This is a thread locals registry for Active Record. For example:
75
#
8-
# ActiveRecord::RuntimeRegistry.connection_handler
9-
#
10-
# returns the connection handler local to the current thread.
6+
# ActiveRecord::RuntimeRegistry.sql_runtime
117
#
12-
# See the documentation of ActiveSupport::PerThreadRegistry
13-
# for further details.
14-
class RuntimeRegistry # :nodoc:
15-
extend ActiveSupport::PerThreadRegistry
8+
# returns the connection handler local to the current unit of execution (either thread of fiber).
9+
module RuntimeRegistry # :nodoc:
10+
extend self
1611

17-
attr_accessor :sql_runtime
12+
def sql_runtime
13+
ActiveSupport::IsolatedExecutionState[:active_record_sql_runtime]
14+
end
1815

19-
def self.sql_runtime; instance.sql_runtime; end
20-
def self.sql_runtime=(x); instance.sql_runtime = x; end
16+
def sql_runtime=(runtime)
17+
ActiveSupport::IsolatedExecutionState[:active_record_sql_runtime] = runtime
18+
end
2119
end
2220
end

activerecord/lib/active_record/scoping.rb

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# frozen_string_literal: true
22

3-
require "active_support/per_thread_registry"
3+
require "active_support/core_ext/module/delegation"
44

55
module ActiveRecord
66
module Scoping
@@ -57,48 +57,60 @@ def initialize_internals_callback # :nodoc:
5757
end
5858

5959
# This class stores the +:current_scope+ and +:ignore_default_scope+ values
60-
# for different classes. The registry is stored as a thread local, which is
61-
# accessed through +ScopeRegistry.current+.
60+
# for different classes. The registry is stored as either a thread or fiber
61+
# local depending on the application configuration.
6262
#
6363
# This class allows you to store and get the scope values on different
6464
# classes and different types of scopes. For example, if you are attempting
6565
# to get the current_scope for the +Board+ model, then you would use the
6666
# following code:
6767
#
6868
# registry = ActiveRecord::Scoping::ScopeRegistry
69-
# registry.set_value_for(:current_scope, Board, some_new_scope)
69+
# registry.set_current_scope(Board, some_new_scope)
7070
#
7171
# Now when you run:
7272
#
73-
# registry.value_for(:current_scope, Board)
73+
# registry.current_scope(Board)
7474
#
75-
# You will obtain whatever was defined in +some_new_scope+. The #value_for
76-
# and #set_value_for methods are delegated to the current ScopeRegistry
77-
# object, so the above example code can also be called as:
78-
#
79-
# ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope,
80-
# Board, some_new_scope)
75+
# You will obtain whatever was defined in +some_new_scope+.
8176
class ScopeRegistry # :nodoc:
82-
extend ActiveSupport::PerThreadRegistry
77+
class << self
78+
delegate :current_scope, :set_current_scope, :ignore_default_scope, :set_ignore_default_scope,
79+
:global_current_scope, :set_global_current_scope, to: :instance
8380

84-
VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope, :global_current_scope]
81+
def instance
82+
ActiveSupport::IsolatedExecutionState[:active_record_scope_registry] ||= new
83+
end
84+
end
8585

8686
def initialize
8787
@current_scope = {}
8888
@ignore_default_scope = {}
8989
@global_current_scope = {}
9090
end
9191

92-
VALID_SCOPE_TYPES.each do |type|
93-
class_eval <<-eorb, __FILE__, __LINE__
94-
def #{type}(model, skip_inherited_scope = false)
95-
value_for(@#{type}, model, skip_inherited_scope)
96-
end
92+
def current_scope(model, skip_inherited_scope = false)
93+
value_for(@current_scope, model, skip_inherited_scope)
94+
end
9795

98-
def set_#{type}(model, value)
99-
set_value_for(@#{type}, model, value)
100-
end
101-
eorb
96+
def set_current_scope(model, value)
97+
set_value_for(@current_scope, model, value)
98+
end
99+
100+
def ignore_default_scope(model, skip_inherited_scope = false)
101+
value_for(@ignore_default_scope, model, skip_inherited_scope)
102+
end
103+
104+
def set_ignore_default_scope(model, value)
105+
set_value_for(@ignore_default_scope, model, value)
106+
end
107+
108+
def global_current_scope(model, skip_inherited_scope = false)
109+
value_for(@global_current_scope, model, skip_inherited_scope)
110+
end
111+
112+
def set_global_current_scope(model, value)
113+
set_value_for(@global_current_scope, model, value)
102114
end
103115

104116
private

activerecord/lib/active_record/suppressor.rb

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,28 @@ module ActiveRecord
3030
module Suppressor
3131
extend ActiveSupport::Concern
3232

33+
class << self
34+
def registry # :nodoc:
35+
ActiveSupport::IsolatedExecutionState[:active_record_suppresor_registry] ||= {}
36+
end
37+
end
38+
3339
module ClassMethods
3440
def suppress(&block)
35-
previous_state = SuppressorRegistry.suppressed[name]
36-
SuppressorRegistry.suppressed[name] = true
41+
previous_state = Suppressor.registry[name]
42+
Suppressor.registry[name] = true
3743
yield
3844
ensure
39-
SuppressorRegistry.suppressed[name] = previous_state
45+
Suppressor.registry[name] = previous_state
4046
end
4147
end
4248

4349
def save(**) # :nodoc:
44-
SuppressorRegistry.suppressed[self.class.name] ? true : super
50+
Suppressor.registry[self.class.name] ? true : super
4551
end
4652

4753
def save!(**) # :nodoc:
48-
SuppressorRegistry.suppressed[self.class.name] ? true : super
49-
end
50-
end
51-
52-
class SuppressorRegistry # :nodoc:
53-
extend ActiveSupport::PerThreadRegistry
54-
55-
attr_reader :suppressed
56-
57-
def initialize
58-
@suppressed = {}
54+
Suppressor.registry[self.class.name] ? true : super
5955
end
6056
end
6157
end

activesupport/lib/active_support.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ module ActiveSupport
5151
autoload :IsolatedExecutionState
5252
autoload :Notifications
5353
autoload :Reloader
54+
autoload :PerThreadRegistry
5455
autoload :SecureCompareRotator
5556

5657
eager_autoload do

activesupport/lib/active_support/cache/strategy/local_cache.rb

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
# frozen_string_literal: true
22

33
require "active_support/core_ext/string/inflections"
4-
require "active_support/per_thread_registry"
54

65
module ActiveSupport
76
module Cache
@@ -13,23 +12,18 @@ module LocalCache
1312
autoload :Middleware, "active_support/cache/strategy/local_cache_middleware"
1413

1514
# Class for storing and registering the local caches.
16-
class LocalCacheRegistry # :nodoc:
17-
extend ActiveSupport::PerThreadRegistry
18-
19-
def initialize
20-
@registry = {}
21-
end
15+
module LocalCacheRegistry # :nodoc:
16+
extend self
2217

2318
def cache_for(local_cache_key)
24-
@registry[local_cache_key]
19+
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
20+
registry[local_cache_key]
2521
end
2622

2723
def set_cache_for(local_cache_key, value)
28-
@registry[local_cache_key] = value
24+
registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
25+
registry[local_cache_key] = value
2926
end
30-
31-
def self.set_cache_for(l, v); instance.set_cache_for l, v; end
32-
def self.cache_for(l); instance.cache_for l; end
3327
end
3428

3529
# Simple memory backed cache. This cache is not thread safe and is intended only

activesupport/lib/active_support/notifications.rb

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
require "active_support/notifications/instrumenter"
44
require "active_support/notifications/fanout"
5-
require "active_support/per_thread_registry"
65

76
module ActiveSupport
87
# = Notifications
@@ -261,28 +260,13 @@ def unsubscribe(subscriber_or_name)
261260
end
262261

263262
def instrumenter
264-
InstrumentationRegistry.instance.instrumenter_for(notifier)
265-
end
266-
end
267-
268-
# This class is a registry which holds all of the +Instrumenter+ objects
269-
# in a particular thread local. To access the +Instrumenter+ object for a
270-
# particular +notifier+, you can call the following method:
271-
#
272-
# InstrumentationRegistry.instrumenter_for(notifier)
273-
#
274-
# The instrumenters for multiple notifiers are held in a single instance of
275-
# this class.
276-
class InstrumentationRegistry # :nodoc:
277-
extend ActiveSupport::PerThreadRegistry
278-
279-
def initialize
280-
@registry = {}
263+
registry[notifier] ||= Instrumenter.new(notifier)
281264
end
282265

283-
def instrumenter_for(notifier)
284-
@registry[notifier] ||= Instrumenter.new(notifier)
285-
end
266+
private
267+
def registry
268+
ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {}
269+
end
286270
end
287271

288272
self.notifier = Fanout.new

activesupport/lib/active_support/per_thread_registry.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ module ActiveSupport
4040
# If the class has an initializer, it must accept no arguments.
4141
module PerThreadRegistry
4242
def self.extended(object)
43+
ActiveSupport::Deprecation.warn(<<~MSG)
44+
ActiveSupport::PerThreadRegistry is deprecated and will be removed in Rails 7.1.
45+
Use `Module#thread_mattr_accessor` instead.
46+
MSG
4347
object.instance_variable_set :@per_thread_registry_key, object.name.freeze
4448
end
4549

0 commit comments

Comments
 (0)