aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorMatthew Draper <matthew@trebex.net>2016-11-06 02:19:57 -0500
committerMatthew Draper <matthew@trebex.net>2016-11-06 02:19:57 -0500
commit3c785bdceed4bdf67708197aa687ced6728d77f3 (patch)
treea49f06ed4b0cd57e4d81b96e851bfd549a019bc7 /activerecord
parenta6d14df40f81ae766081e6a5d4e5fa428eca3174 (diff)
downloadrails-3c785bdceed4bdf67708197aa687ced6728d77f3.tar.gz
rails-3c785bdceed4bdf67708197aa687ced6728d77f3.tar.bz2
rails-3c785bdceed4bdf67708197aa687ced6728d77f3.zip
Configure query caching (per thread) on the connection pool
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb27
-rw-r--r--activerecord/lib/active_record/query_cache.rb11
-rw-r--r--activerecord/test/cases/query_cache_test.rb34
4 files changed, 71 insertions, 2 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index e9ecb78e27..8ce28eae62 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -307,6 +307,7 @@ module ActiveRecord
end
include MonitorMixin
+ include QueryCache::ConnectionPoolConfiguration
attr_accessor :automatic_reconnect, :checkout_timeout, :schema_cache
attr_reader :spec, :connections, :size, :reaper
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index d4229dfdba..7eab7de5d3 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -4,6 +4,8 @@ module ActiveRecord
class << self
def included(base) #:nodoc:
dirties_query_cache base, :insert, :update, :delete, :rollback_to_savepoint, :rollback_db_transaction
+
+ base.set_callback :checkout, :after, :configure_query_cache!
base.set_callback :checkin, :after, :disable_query_cache!
end
@@ -19,6 +21,27 @@ module ActiveRecord
end
end
+ module ConnectionPoolConfiguration
+ def initialize(*)
+ super
+ @query_cache_enabled = Concurrent::Map.new { false }
+ end
+
+ def enable_query_cache!
+ @query_cache_enabled[connection_cache_key(Thread.current)] = true
+ connection.enable_query_cache! if active_connection?
+ end
+
+ def disable_query_cache!
+ @query_cache_enabled.delete connection_cache_key(Thread.current)
+ connection.disable_query_cache! if active_connection?
+ end
+
+ def query_cache_enabled
+ @query_cache_enabled[connection_cache_key(Thread.current)]
+ end
+ end
+
attr_reader :query_cache, :query_cache_enabled
def initialize(*)
@@ -98,6 +121,10 @@ module ActiveRecord
def locked?(arel)
arel.respond_to?(:locked) && arel.locked
end
+
+ def configure_query_cache!
+ enable_query_cache! if pool.query_cache_enabled
+ end
end
end
end
diff --git a/activerecord/lib/active_record/query_cache.rb b/activerecord/lib/active_record/query_cache.rb
index 667bfe96f6..ec246e97bc 100644
--- a/activerecord/lib/active_record/query_cache.rb
+++ b/activerecord/lib/active_record/query_cache.rb
@@ -24,10 +24,17 @@ module ActiveRecord
end
def self.run
- ActiveRecord::Base.connection.enable_query_cache!
+ caching_pool = ActiveRecord::Base.connection_pool
+ caching_was_enabled = caching_pool.query_cache_enabled
+
+ caching_pool.enable_query_cache!
+
+ [caching_pool, caching_was_enabled]
end
- def self.complete(_)
+ def self.complete((caching_pool, caching_was_enabled))
+ caching_pool.disable_query_cache! unless caching_was_enabled
+
ActiveRecord::Base.connection_handler.connection_pool_list.each do |pool|
pool.release_connection if pool.active_connection? && !pool.connection.transaction_open?
end
diff --git a/activerecord/test/cases/query_cache_test.rb b/activerecord/test/cases/query_cache_test.rb
index 5b0477aabe..90054ce83d 100644
--- a/activerecord/test/cases/query_cache_test.rb
+++ b/activerecord/test/cases/query_cache_test.rb
@@ -313,6 +313,40 @@ class QueryCacheTest < ActiveRecord::TestCase
end
end
+ def test_query_cache_does_not_establish_connection_if_unconnected
+ ActiveRecord::Base.clear_active_connections!
+ refute ActiveRecord::Base.connection_handler.active_connections? # sanity check
+
+ middleware {
+ refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in setup"
+ }.call({})
+
+ refute ActiveRecord::Base.connection_handler.active_connections?, "QueryCache forced ActiveRecord::Base to establish a connection in cleanup"
+ end
+
+ def test_query_cache_is_enabled_on_connections_established_after_middleware_runs
+ ActiveRecord::Base.clear_active_connections!
+ refute ActiveRecord::Base.connection_handler.active_connections? # sanity check
+
+ middleware {
+ assert ActiveRecord::Base.connection.query_cache_enabled, "QueryCache did not get lazily enabled"
+ }.call({})
+ end
+
+ def test_query_caching_is_local_to_the_current_thread
+ ActiveRecord::Base.clear_active_connections!
+
+ middleware {
+ assert ActiveRecord::Base.connection_pool.query_cache_enabled
+ assert ActiveRecord::Base.connection.query_cache_enabled
+
+ Thread.new {
+ refute ActiveRecord::Base.connection_pool.query_cache_enabled
+ refute ActiveRecord::Base.connection.query_cache_enabled
+ }.join
+ }.call({})
+ end
+
private
def middleware(&app)
executor = Class.new(ActiveSupport::Executor)