Changeset 3693
- Timestamp:
- 02/27/06 21:37:30 (4 years ago)
- Files:
-
- trunk/activerecord/CHANGELOG (modified) (1 diff)
- trunk/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb (modified) (3 diffs)
- trunk/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb (modified) (6 diffs)
- trunk/railties/lib/dispatcher.rb (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/activerecord/CHANGELOG
r3691 r3693 1 1 *SVN* 2 3 * Speed up class -> connection caching and stale connection verification. #3979 [Stefan Kaes] 2 4 3 5 * Add set_fixture_class to allow the use of table name accessors with models which use set_table_name. [Kevin Clark] trunk/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
r3674 r3693 22 22 include Quoting, DatabaseStatements, SchemaStatements 23 23 @@row_even = true 24 24 25 25 def initialize(connection, logger = nil) #:nodoc: 26 26 @connection, @logger = connection, logger 27 27 @runtime = 0 28 @last_verification = 0 28 29 end 29 30 … … 77 78 end 78 79 80 # Lazily verify this connection, calling +active?+ only if it hasn't 81 # been called for +timeout+ seconds. 82 def verify!(timeout) 83 now = Time.now.to_i 84 if (now - @last_verification) > timeout 85 reconnect! unless active? 86 @last_verification = now 87 end 88 end 79 89 80 90 protected … … 96 106 rescue Exception => e 97 107 # Log message and raise exception. 108 # Set last_verfication to 0, so that connection gets verified 109 # upon reentering the request loop 110 @last_verification = 0 98 111 message = "#{e.class.name}: #{e.message}: #{sql}" 99 112 log_info(message, name, 0) trunk/activerecord/lib/active_record/connection_adapters/abstract/connection_specification.rb
r3674 r3693 8 8 end 9 9 10 # Check connections for active? after +@@connection_cache_timeout+ seconds 11 # defaults to 5 minutes 12 cattr_accessor :connection_cache_timeout 13 @@connection_cache_timeout = 300 14 10 15 # The class -> [adapter_method, config] map 11 16 @@defined_connections = {} 12 17 13 # The class -> thread id -> adapter cache. 14 @@connection_cache = Hash.new { |h, k| h[k] = Hash.new } 15 18 # The class -> thread id -> adapter cache. (class -> adapter if not allow_concurrency) 19 @@connection_cache = {} 20 21 # retrieve the connection cache 22 def self.connection_cache 23 if @@allow_concurrency 24 @@connection_cache[Thread.current.object_id] ||= {} 25 else 26 @@connection_cache 27 end 28 end 29 30 @connection_cache_key = nil 31 def self.connection_cache_key 32 @connection_cache_key ||= 33 if active_connections[name] || @@defined_connections[name] 34 name 35 elsif self == ActiveRecord::Base 36 nil 37 else 38 superclass.connection_cache_key 39 end 40 end 41 42 def self.clear_connection_cache_key 43 @connection_cache_key = nil 44 subclasses.each{|klass| klass.clear_connection_cache_key } 45 end 46 16 47 # Returns the connection currently associated with the class. This can 17 48 # also be used to "borrow" the connection to do database work unrelated 18 49 # to any of the specific Active Records. 19 50 def self.connection 20 @@connection_cache[Thread.current.object_id][name] ||= retrieve_connection 51 if (cache_key = @connection_cache_key) && (conn = connection_cache[cache_key]) 52 conn 53 else 54 conn = retrieve_connection # this will set @connection_cache_key 55 connection_cache[@connection_cache_key] = conn 56 end 21 57 end 22 58 23 59 # Clears the cache which maps classes to connections. 24 60 def self.clear_connection_cache! 25 @@connection_cache.clear 26 end 27 61 if @@allow_concurrency 62 @@connection_cache.delete(Thread.current.object_id) 63 else 64 @@connection_cache = {} 65 end 66 end 67 68 # Verify connection cache. 69 def self.verify_connection_cache! 70 timeout = @@connection_cache_timeout 71 connection_cache.each_value { |connection| connection.verify!(timeout) } 72 end 73 28 74 # Returns the connection currently associated with the class. This can 29 75 # also be used to "borrow" the connection to do database work that isn't … … 66 112 establish_connection(RAILS_ENV) 67 113 when ConnectionSpecification 114 clear_connection_cache_key 115 @connection_cache_key = name 68 116 @@defined_connections[name] = spec 69 117 when Symbol, String … … 84 132 85 133 def self.active_connections #:nodoc: 86 if allow_concurrency134 if @@allow_concurrency 87 135 Thread.current['active_connections'] ||= {} 88 136 else … … 96 144 # for (not necessarily the current class). 97 145 def self.retrieve_connection #:nodoc: 98 klass = self 99 ar_super = ActiveRecord::Base.superclass 100 until klass == ar_super 101 if conn = active_connections[klass.name] 102 # Reconnect if the connection is inactive. 103 conn.reconnect! unless conn.active? 104 return conn 105 elsif conn = @@defined_connections[klass.name] 106 # Activate this connection specification. 107 klass.connection = conn 108 return self.connection 109 end 110 klass = klass.superclass 111 end 112 raise ConnectionNotEstablished 146 cache_key = connection_cache_key 147 # cache_key is nil if establish_connection hasn't been called for 148 # some class along the inheritance chain up to AR::Base yet 149 raise ConnectionNotEstablished unless cache_key 150 if conn = active_connections[cache_key] 151 # Verify the connection. 152 conn.verify!(@@connection_cache_timeout) 153 return conn 154 elsif conn = @@defined_connections[cache_key] 155 # Activate this connection specification. 156 klass = cache_key.constantize 157 klass.connection = conn 158 return active_connections[cache_key] 159 else 160 raise ConnectionNotEstablished 161 end 113 162 end 114 163 115 164 # Returns true if a connection that's accessible to this class have already been opened. 116 165 def self.connected? 117 klass = self 118 until klass == ActiveRecord::Base.superclass 119 if active_connections[klass.name] 120 return true 121 else 122 klass = klass.superclass 123 end 124 end 125 return false 166 active_connections[connection_cache_key] ? true : false 126 167 end 127 168 … … 134 175 konn = active_connections[klass.name] 135 176 @@defined_connections.delete_if { |key, value| value == spec } 136 @@connection_cache[Thread.current.object_id].delete_if { |key, value| value == konn }177 connection_cache.delete_if { |key, value| value == konn } 137 178 active_connections.delete_if { |key, value| value == konn } 138 179 konn.disconnect! if konn … … 152 193 end 153 194 end 195 196 # connection state logging 197 def self.log_connections 198 if logger 199 logger.info "Defined connections: #{@@defined_connections.inspect}" 200 logger.info "Active connections: #{active_connections.inspect}" 201 logger.info "Connection cache: #{connection_cache.inspect}" 202 logger.info "Connection cache key: #{@connection_cache_key}" 203 end 204 end 154 205 end 155 206 end trunk/railties/lib/dispatcher.rb
r3526 r3693 68 68 prepare_breakpoint 69 69 require_dependency('application.rb') unless Object.const_defined?(:ApplicationController) 70 ActiveRecord::Base.verify_connection_cache! 70 71 end 71 72 72 73 def reset_after_dispatch 73 74 reset_application! if Dependencies.load? 74 ActiveRecord::Base.clear_connection_cache!75 75 Breakpoint.deactivate_drb if defined?(BREAKPOINT_SERVER_PORT) 76 # ActiveRecord::Base.clear_connection_cache! 76 77 end 77 78