aboutsummaryrefslogblamecommitdiffstats
path: root/activesupport/lib/active_support/per_thread_registry.rb
blob: e9499600a4466b749e0e0b99280b789c437fd26b (plain) (tree)
1
2
3
4
5
6
7
8
9
                    
                                                                        
   




                                                     
   


                                                 
   


                                           
   
                                                                   
   
                                                                           
   
                                                              

                                                      
   





                                                                               
   
                                                                 
                          

             
                                                       













                                                                             


         
module ActiveSupport
  # This module is used to encapsulate access to thread local variables.
  #
  # Instead of polluting the thread locals namespace:
  #
  #   Thread.current[:connection_handler]
  #
  # you define a class that extends this module:
  #
  #   module ActiveRecord
  #     class RuntimeRegistry
  #       extend ActiveSupport::PerThreadRegistry
  #
  #       attr_accessor :connection_handler
  #     end
  #   end
  #
  # and invoke the declared instance accessors as class methods. So
  #
  #   ActiveRecord::RuntimeRegistry.connection_handler = connection_handler
  #
  # sets a connection handler local to the current thread, and
  #
  #   ActiveRecord::RuntimeRegistry.connection_handler
  #
  # 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.
  #
  # If the class has an initializer, it must accept no arguments.
  module PerThreadRegistry
    protected

      def method_missing(name, *args, &block) # :nodoc:
        # Caches the method definition as a singleton method of the receiver.
        singleton_class.class_eval do
          define_method(name) do |*a, &b|
            per_thread_registry_instance.public_send(name, *a, &b)
          end
        end

        send(name, *args, &block)
      end

    private

      def per_thread_registry_instance
        Thread.current[name] ||= new
      end
  end
end