Eliminate internal uses of `PerThreadRegistry` and deprecate it

This module has been soft deprecated for a long time, but since
it was used internally it wasn't throwing deprecation warnings.

Now we can throw a deprecation warning.
This commit is contained in:
Jean Boussier 2021-11-19 10:41:01 +01:00
parent ffb3a3e01a
commit b4eae47bbe
12 changed files with 101 additions and 122 deletions

View File

@ -292,19 +292,20 @@ module ActionView
controller.write_fragment(name, fragment, options) controller.write_fragment(name, fragment, options)
end end
class CachingRegistry module CachingRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry extend self
attr_accessor :caching def caching?
alias caching? caching ActiveSupport::IsolatedExecutionState[:action_view_caching] ||= false
end
def self.track_caching def track_caching
caching_was = self.caching caching_was = ActiveSupport::IsolatedExecutionState[:action_view_caching]
self.caching = true ActiveSupport::IsolatedExecutionState[:action_view_caching] = true
yield yield
ensure ensure
self.caching = caching_was ActiveSupport::IsolatedExecutionState[:action_view_caching] = caching_was
end end
end end
end end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
require "active_support/per_thread_registry" require "active_support/core_ext/module/delegation"
module ActiveRecord module ActiveRecord
# This is a thread locals registry for EXPLAIN. For example # This is a thread locals registry for EXPLAIN. For example
@ -8,13 +8,18 @@ module ActiveRecord
# ActiveRecord::ExplainRegistry.queries # ActiveRecord::ExplainRegistry.queries
# #
# returns the collected queries local to the current thread. # returns the collected queries local to the current thread.
#
# See the documentation of ActiveSupport::PerThreadRegistry
# for further details.
class ExplainRegistry # :nodoc: class ExplainRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry class << self
delegate :reset, :collect, :collect=, :collect?, :queries, to: :instance
attr_accessor :queries, :collect private
def instance
ActiveSupport::IsolatedExecutionState[:active_record_explain_registry] ||= new
end
end
attr_accessor :collect
attr_reader :queries
def initialize def initialize
reset reset

View File

@ -31,17 +31,15 @@ module ActiveRecord
end end
# :startdoc: # :startdoc:
class QueryRegistry # :nodoc: module QueryRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry extend self
attr_reader :queries def queries
ActiveSupport::IsolatedExecutionState[:active_record_query_registry] ||= []
def initialize
@queries = []
end end
def reset def reset
@queries.clear queries.clear
end end
end end
end end

View File

@ -1,22 +1,20 @@
# frozen_string_literal: true # frozen_string_literal: true
require "active_support/per_thread_registry"
module ActiveRecord module ActiveRecord
# This is a thread locals registry for Active Record. For example: # This is a thread locals registry for Active Record. For example:
# #
# ActiveRecord::RuntimeRegistry.connection_handler # ActiveRecord::RuntimeRegistry.sql_runtime
# #
# returns the connection handler local to the current thread. # returns the connection handler local to the current unit of execution (either thread of fiber).
# module RuntimeRegistry # :nodoc:
# See the documentation of ActiveSupport::PerThreadRegistry extend self
# for further details.
class RuntimeRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_accessor :sql_runtime def sql_runtime
ActiveSupport::IsolatedExecutionState[:active_record_sql_runtime]
end
def self.sql_runtime; instance.sql_runtime; end def sql_runtime=(runtime)
def self.sql_runtime=(x); instance.sql_runtime = x; end ActiveSupport::IsolatedExecutionState[:active_record_sql_runtime] = runtime
end
end end
end end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
require "active_support/per_thread_registry" require "active_support/core_ext/module/delegation"
module ActiveRecord module ActiveRecord
module Scoping module Scoping
@ -57,8 +57,8 @@ module ActiveRecord
end end
# This class stores the +:current_scope+ and +:ignore_default_scope+ values # This class stores the +:current_scope+ and +:ignore_default_scope+ values
# for different classes. The registry is stored as a thread local, which is # for different classes. The registry is stored as either a thread or fiber
# accessed through +ScopeRegistry.current+. # local depending on the application configuration.
# #
# This class allows you to store and get the scope values on different # This class allows you to store and get the scope values on different
# classes and different types of scopes. For example, if you are attempting # classes and different types of scopes. For example, if you are attempting
@ -66,22 +66,22 @@ module ActiveRecord
# following code: # following code:
# #
# registry = ActiveRecord::Scoping::ScopeRegistry # registry = ActiveRecord::Scoping::ScopeRegistry
# registry.set_value_for(:current_scope, Board, some_new_scope) # registry.set_current_scope(Board, some_new_scope)
# #
# Now when you run: # Now when you run:
# #
# registry.value_for(:current_scope, Board) # registry.current_scope(Board)
# #
# You will obtain whatever was defined in +some_new_scope+. The #value_for # You will obtain whatever was defined in +some_new_scope+.
# and #set_value_for methods are delegated to the current ScopeRegistry
# object, so the above example code can also be called as:
#
# ActiveRecord::Scoping::ScopeRegistry.set_value_for(:current_scope,
# Board, some_new_scope)
class ScopeRegistry # :nodoc: class ScopeRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry class << self
delegate :current_scope, :set_current_scope, :ignore_default_scope, :set_ignore_default_scope,
:global_current_scope, :set_global_current_scope, to: :instance
VALID_SCOPE_TYPES = [:current_scope, :ignore_default_scope, :global_current_scope] def instance
ActiveSupport::IsolatedExecutionState[:active_record_scope_registry] ||= new
end
end
def initialize def initialize
@current_scope = {} @current_scope = {}
@ -89,16 +89,28 @@ module ActiveRecord
@global_current_scope = {} @global_current_scope = {}
end end
VALID_SCOPE_TYPES.each do |type| def current_scope(model, skip_inherited_scope = false)
class_eval <<-eorb, __FILE__, __LINE__ value_for(@current_scope, model, skip_inherited_scope)
def #{type}(model, skip_inherited_scope = false) end
value_for(@#{type}, model, skip_inherited_scope)
end
def set_#{type}(model, value) def set_current_scope(model, value)
set_value_for(@#{type}, model, value) set_value_for(@current_scope, model, value)
end end
eorb
def ignore_default_scope(model, skip_inherited_scope = false)
value_for(@ignore_default_scope, model, skip_inherited_scope)
end
def set_ignore_default_scope(model, value)
set_value_for(@ignore_default_scope, model, value)
end
def global_current_scope(model, skip_inherited_scope = false)
value_for(@global_current_scope, model, skip_inherited_scope)
end
def set_global_current_scope(model, value)
set_value_for(@global_current_scope, model, value)
end end
private private

View File

@ -30,32 +30,28 @@ module ActiveRecord
module Suppressor module Suppressor
extend ActiveSupport::Concern extend ActiveSupport::Concern
class << self
def registry # :nodoc:
ActiveSupport::IsolatedExecutionState[:active_record_suppresor_registry] ||= {}
end
end
module ClassMethods module ClassMethods
def suppress(&block) def suppress(&block)
previous_state = SuppressorRegistry.suppressed[name] previous_state = Suppressor.registry[name]
SuppressorRegistry.suppressed[name] = true Suppressor.registry[name] = true
yield yield
ensure ensure
SuppressorRegistry.suppressed[name] = previous_state Suppressor.registry[name] = previous_state
end end
end end
def save(**) # :nodoc: def save(**) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super Suppressor.registry[self.class.name] ? true : super
end end
def save!(**) # :nodoc: def save!(**) # :nodoc:
SuppressorRegistry.suppressed[self.class.name] ? true : super Suppressor.registry[self.class.name] ? true : super
end
end
class SuppressorRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
attr_reader :suppressed
def initialize
@suppressed = {}
end end
end end
end end

View File

@ -51,6 +51,7 @@ module ActiveSupport
autoload :IsolatedExecutionState autoload :IsolatedExecutionState
autoload :Notifications autoload :Notifications
autoload :Reloader autoload :Reloader
autoload :PerThreadRegistry
autoload :SecureCompareRotator autoload :SecureCompareRotator
eager_autoload do eager_autoload do

View File

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
require "active_support/core_ext/string/inflections" require "active_support/core_ext/string/inflections"
require "active_support/per_thread_registry"
module ActiveSupport module ActiveSupport
module Cache module Cache
@ -13,23 +12,18 @@ module ActiveSupport
autoload :Middleware, "active_support/cache/strategy/local_cache_middleware" autoload :Middleware, "active_support/cache/strategy/local_cache_middleware"
# Class for storing and registering the local caches. # Class for storing and registering the local caches.
class LocalCacheRegistry # :nodoc: module LocalCacheRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry extend self
def initialize
@registry = {}
end
def cache_for(local_cache_key) def cache_for(local_cache_key)
@registry[local_cache_key] registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
registry[local_cache_key]
end end
def set_cache_for(local_cache_key, value) def set_cache_for(local_cache_key, value)
@registry[local_cache_key] = value registry = ActiveSupport::IsolatedExecutionState[:active_support_local_cache_registry] ||= {}
registry[local_cache_key] = value
end end
def self.set_cache_for(l, v); instance.set_cache_for l, v; end
def self.cache_for(l); instance.cache_for l; end
end end
# Simple memory backed cache. This cache is not thread safe and is intended only # Simple memory backed cache. This cache is not thread safe and is intended only

View File

@ -2,7 +2,6 @@
require "active_support/notifications/instrumenter" require "active_support/notifications/instrumenter"
require "active_support/notifications/fanout" require "active_support/notifications/fanout"
require "active_support/per_thread_registry"
module ActiveSupport module ActiveSupport
# = Notifications # = Notifications
@ -261,28 +260,13 @@ module ActiveSupport
end end
def instrumenter def instrumenter
InstrumentationRegistry.instance.instrumenter_for(notifier) registry[notifier] ||= Instrumenter.new(notifier)
end
end
# This class is a registry which holds all of the +Instrumenter+ objects
# in a particular thread local. To access the +Instrumenter+ object for a
# particular +notifier+, you can call the following method:
#
# InstrumentationRegistry.instrumenter_for(notifier)
#
# The instrumenters for multiple notifiers are held in a single instance of
# this class.
class InstrumentationRegistry # :nodoc:
extend ActiveSupport::PerThreadRegistry
def initialize
@registry = {}
end end
def instrumenter_for(notifier) private
@registry[notifier] ||= Instrumenter.new(notifier) def registry
end ActiveSupport::IsolatedExecutionState[:active_support_notifications_registry] ||= {}
end
end end
self.notifier = Fanout.new self.notifier = Fanout.new

View File

@ -40,6 +40,10 @@ module ActiveSupport
# If the class has an initializer, it must accept no arguments. # If the class has an initializer, it must accept no arguments.
module PerThreadRegistry module PerThreadRegistry
def self.extended(object) def self.extended(object)
ActiveSupport::Deprecation.warn(<<~MSG)
ActiveSupport::PerThreadRegistry is deprecated and will be removed in Rails 7.1.
Use `Module#thread_mattr_accessor` instead.
MSG
object.instance_variable_set :@per_thread_registry_key, object.name.freeze object.instance_variable_set :@per_thread_registry_key, object.name.freeze
end end

View File

@ -1,6 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require "active_support/per_thread_registry"
require "active_support/notifications" require "active_support/notifications"
module ActiveSupport module ActiveSupport
@ -157,23 +156,8 @@ module ActiveSupport
private private
def event_stack def event_stack
SubscriberQueueRegistry.instance.get_queue(@queue_key) registry = ActiveSupport::IsolatedExecutionState[:active_support_subscriber_queue_registry] ||= {}
registry[@queue_key] ||= []
end end
end end
# This is a registry for all the event stacks kept for subscribers.
#
# See the documentation of <tt>ActiveSupport::PerThreadRegistry</tt>
# for further details.
class SubscriberQueueRegistry # :nodoc:
extend PerThreadRegistry
def initialize
@registry = {}
end
def get_queue(queue_key)
@registry[queue_key] ||= []
end
end
end end

View File

@ -4,7 +4,9 @@ require_relative "abstract_unit"
class PerThreadRegistryTest < ActiveSupport::TestCase class PerThreadRegistryTest < ActiveSupport::TestCase
class TestRegistry class TestRegistry
extend ActiveSupport::PerThreadRegistry ActiveSupport::Deprecation.silence do
extend ActiveSupport::PerThreadRegistry
end
def foo(x:); x; end def foo(x:); x; end
end end