2017-07-09 08:06:36 -04:00
|
|
|
# frozen_string_literal: true
|
2017-07-10 09:39:13 -04:00
|
|
|
|
2017-10-21 09:11:29 -04:00
|
|
|
require "active_support/core_ext/module/delegation"
|
2015-11-18 19:31:31 -05:00
|
|
|
|
2013-04-09 12:04:39 -04:00
|
|
|
module ActiveSupport
|
2016-06-24 16:14:50 -04:00
|
|
|
# NOTE: This approach has been deprecated for end-user code in favor of {thread_mattr_accessor}[rdoc-ref:Module#thread_mattr_accessor] and friends.
|
2015-12-17 08:28:19 -05:00
|
|
|
# Please use that approach instead.
|
|
|
|
#
|
2013-04-13 02:15:11 -04:00
|
|
|
# This module is used to encapsulate access to thread local variables.
|
2013-04-09 12:04:39 -04:00
|
|
|
#
|
2013-04-13 11:08:00 -04:00
|
|
|
# Instead of polluting the thread locals namespace:
|
|
|
|
#
|
|
|
|
# Thread.current[:connection_handler]
|
|
|
|
#
|
|
|
|
# you define a class that extends this module:
|
2013-04-09 12:04:39 -04:00
|
|
|
#
|
2013-04-13 02:15:11 -04:00
|
|
|
# module ActiveRecord
|
|
|
|
# class RuntimeRegistry
|
|
|
|
# extend ActiveSupport::PerThreadRegistry
|
2013-04-09 12:04:39 -04:00
|
|
|
#
|
2013-04-13 02:15:11 -04:00
|
|
|
# attr_accessor :connection_handler
|
|
|
|
# end
|
|
|
|
# end
|
2013-04-09 12:04:39 -04:00
|
|
|
#
|
2013-04-13 11:08:00 -04:00
|
|
|
# and invoke the declared instance accessors as class methods. So
|
2013-04-13 02:15:11 -04:00
|
|
|
#
|
2013-04-13 11:08:00 -04:00
|
|
|
# ActiveRecord::RuntimeRegistry.connection_handler = connection_handler
|
2013-04-13 02:15:11 -04:00
|
|
|
#
|
2013-04-13 11:08:00 -04:00
|
|
|
# sets a connection handler local to the current thread, and
|
2013-04-13 02:15:11 -04:00
|
|
|
#
|
|
|
|
# ActiveRecord::RuntimeRegistry.connection_handler
|
2013-04-09 12:04:39 -04:00
|
|
|
#
|
2013-04-13 11:08:00 -04:00
|
|
|
# returns a connection handler local to the current thread.
|
|
|
|
#
|
|
|
|
# This feature is accomplished by instantiating the class and storing the
|
|
|
|
# instance as a thread local keyed by the class name. In the example above
|
|
|
|
# a key "ActiveRecord::RuntimeRegistry" is stored in <tt>Thread.current</tt>.
|
|
|
|
# The class methods proxy to said thread local instance.
|
2013-04-09 12:04:39 -04:00
|
|
|
#
|
2013-04-13 02:15:11 -04:00
|
|
|
# If the class has an initializer, it must accept no arguments.
|
2013-04-09 12:04:39 -04:00
|
|
|
module PerThreadRegistry
|
2013-12-12 20:40:21 -05:00
|
|
|
def self.extended(object)
|
2019-07-30 20:51:41 -04:00
|
|
|
object.instance_variable_set :@per_thread_registry_key, object.name.freeze
|
2013-12-12 20:40:21 -05:00
|
|
|
end
|
|
|
|
|
2013-11-06 19:32:47 -05:00
|
|
|
def instance
|
2013-12-12 20:40:21 -05:00
|
|
|
Thread.current[@per_thread_registry_key] ||= new
|
2013-11-06 19:32:47 -05:00
|
|
|
end
|
|
|
|
|
2016-12-17 03:13:50 -05:00
|
|
|
private
|
|
|
|
def method_missing(name, *args, &block)
|
2013-04-13 11:08:00 -04:00
|
|
|
# Caches the method definition as a singleton method of the receiver.
|
2015-10-08 16:29:51 -04:00
|
|
|
#
|
|
|
|
# By letting #delegate handle it, we avoid an enclosure that'll capture args.
|
|
|
|
singleton_class.delegate name, to: :instance
|
2013-04-13 11:08:00 -04:00
|
|
|
|
|
|
|
send(name, *args, &block)
|
|
|
|
end
|
2013-04-09 12:04:39 -04:00
|
|
|
end
|
|
|
|
end
|