From e0a403edfccd3727e0d92aa3900e649e17488c7d Mon Sep 17 00:00:00 2001 From: Sam Saffron Date: Mon, 16 Sep 2019 17:38:13 +1000 Subject: [PATCH] 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. --- config/unicorn.conf.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/config/unicorn.conf.rb b/config/unicorn.conf.rb index 85b28005f5a..9b140eaf399 100644 --- a/config/unicorn.conf.rb +++ b/config/unicorn.conf.rb @@ -61,6 +61,23 @@ before_fork do |server, worker| table.classify.constantize.first rescue nil 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 Rails.application.routes.recognize_path('abc') rescue nil