1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Invalidate query cache for all connections in the current thread

This change ensures that all query cahces are cleared across all
connections per handler for the current thread so if you write on one
connection the read will have the query cache cleared.
This commit is contained in:
Eileen Uchitelle 2019-01-29 13:18:58 -05:00
parent 79bc9e81c3
commit 183c0eb472
3 changed files with 48 additions and 1 deletions

View file

@ -17,7 +17,7 @@ module ActiveRecord
method_names.each do |method_name|
base.class_eval <<-end_code, __FILE__, __LINE__ + 1
def #{method_name}(*)
clear_query_cache if @query_cache_enabled
ActiveRecord::Base.clear_query_caches_for_current_thread if @query_cache_enabled
super
end
end_code

View file

@ -176,6 +176,15 @@ module ActiveRecord
config_hash
end
# Clears the query cache for all connections associated with the current thread.
def clear_query_caches_for_current_thread
ActiveRecord::Base.connection_handlers.each_value do |handler|
handler.connection_pool_list.each do |pool|
pool.connection.clear_query_cache if pool.active_connection?
end
end
end
# Returns the connection currently associated with the class. This can
# also be used to "borrow" the connection to do database work unrelated
# to any of the specific Active Records.

View file

@ -502,6 +502,44 @@ class QueryCacheTest < ActiveRecord::TestCase
}.call({})
end
def test_clear_query_cache_is_called_on_all_connections
skip "with in memory db, reading role won't be able to see database on writing role" if in_memory_db?
with_temporary_connection_pool do
ActiveRecord::Base.connection_handlers = {
writing: ActiveRecord::Base.default_connection_handler,
reading: ActiveRecord::ConnectionAdapters::ConnectionHandler.new
}
ActiveRecord::Base.connected_to(role: :reading) do
ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations["arunit"])
end
mw = middleware { |env|
ActiveRecord::Base.connected_to(role: :reading) do
@topic = Topic.first
end
assert @topic
ActiveRecord::Base.connected_to(role: :writing) do
@topic.title = "It doesn't have to be crazy at work"
@topic.save!
end
assert_equal "It doesn't have to be crazy at work", @topic.title
ActiveRecord::Base.connected_to(role: :reading) do
@topic = Topic.first
assert_equal "It doesn't have to be crazy at work", @topic.title
end
}
mw.call({})
end
ensure
ActiveRecord::Base.connection_handlers = { writing: ActiveRecord::Base.default_connection_handler }
end
private
def with_temporary_connection_pool