PERF: ensure we warm up schema cache in the entire multisite

This makes sure that all processes that fork off the master have a fully
operation schema cache.

In Rails 6, schema cache is now bolted to the connection pool. This change
ensures the cache on all pools is fully populated prior to forking.

The bolting of cache to connection pool does lead to some strange cases
where a connection can "steal" the cache from another connection, which
can cause stuff to possibly hang or deadlock. This change minimizes the risk
of this happening cause it is already primed.

We make a STRONG assumption that the schema is always the same on all sites
when we spin up a multisite cluster.
This commit is contained in:
Sam Saffron 2019-09-16 17:38:13 +10:00
parent 7fa2ae912c
commit e0a403edfc

View File

@ -61,6 +61,23 @@ before_fork do |server, worker|
table.classify.constantize.first rescue nil table.classify.constantize.first rescue nil
end end
# ensure we have a full schema cache in case we missed something above
ActiveRecord::Base.connection.data_sources.each do |table|
ActiveRecord::Base.connection.schema_cache.add(table)
end
schema_cache = ActiveRecord::Base.connection.schema_cache
# load up schema cache for all multisite assuming all dbs have
# an identical schema
RailsMultisite::ConnectionManagement.each_connection do
dup_cache = schema_cache.dup
# this line is not really needed, but just in case the
# underlying implementation changes lets give it a shot
dup_cache.connection = nil
ActiveRecord::Base.connection.schema_cache = dup_cache
end
# router warm up # router warm up
Rails.application.routes.recognize_path('abc') rescue nil Rails.application.routes.recognize_path('abc') rescue nil