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:
parent
79bc9e81c3
commit
183c0eb472
3 changed files with 48 additions and 1 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue