mirror of
https://github.com/discourse/discourse.git
synced 2024-11-22 13:09:18 +08:00
PREF: optimise preloading application
We preload to ensure as much memory as possible is reused from unicorn master to various workers using copy-on-write (sidekiq, unicorn) This migrates the preloading code into the Discourse module for easier reuse and adds 3 notable preloading changes 1. We attempt to localize a string on each site, ensuring we warmup the i18n 2. We preload all our templates (compiling .erb to class) 3. We warm-up our search tokenizer which uses cppjieba which is a large memory consumer, this will only cause a warmup on CJK sites or sites with the special site setting enabled.
This commit is contained in:
parent
71ea4ad7fc
commit
8d5f47dded
4
Gemfile
4
Gemfile
|
@ -26,6 +26,10 @@ else
|
||||||
gem 'sprockets-rails'
|
gem 'sprockets-rails'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# this will eventually be added to rails,
|
||||||
|
# allows us to precompile all our templates in the unicorn master
|
||||||
|
gem 'actionview_precompiler', require: false
|
||||||
|
|
||||||
gem 'seed-fu'
|
gem 'seed-fu'
|
||||||
|
|
||||||
gem 'mail', require: false
|
gem 'mail', require: false
|
||||||
|
|
|
@ -20,6 +20,8 @@ GEM
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||||
|
actionview_precompiler (0.2.1)
|
||||||
|
actionview (>= 6.0.a)
|
||||||
active_model_serializers (0.8.4)
|
active_model_serializers (0.8.4)
|
||||||
activemodel (>= 3.0)
|
activemodel (>= 3.0)
|
||||||
activejob (6.0.0)
|
activejob (6.0.0)
|
||||||
|
@ -428,6 +430,7 @@ DEPENDENCIES
|
||||||
actionmailer (= 6.0.0)
|
actionmailer (= 6.0.0)
|
||||||
actionpack (= 6.0.0)
|
actionpack (= 6.0.0)
|
||||||
actionview (= 6.0.0)
|
actionview (= 6.0.0)
|
||||||
|
actionview_precompiler
|
||||||
active_model_serializers (~> 0.8.3)
|
active_model_serializers (~> 0.8.3)
|
||||||
activemodel (= 6.0.0)
|
activemodel (= 6.0.0)
|
||||||
activerecord (= 6.0.0)
|
activerecord (= 6.0.0)
|
||||||
|
|
|
@ -53,43 +53,15 @@ initialized = false
|
||||||
before_fork do |server, worker|
|
before_fork do |server, worker|
|
||||||
|
|
||||||
unless initialized
|
unless initialized
|
||||||
# load up the yaml for the localization bits, in master process
|
Discourse.preload_rails!
|
||||||
I18n.t(:posts)
|
|
||||||
|
|
||||||
# load up all models and schema
|
|
||||||
(ActiveRecord::Base.connection.tables - %w[schema_migrations versions]).each do |table|
|
|
||||||
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
|
|
||||||
|
|
||||||
# preload discourse version
|
|
||||||
Discourse.git_version
|
|
||||||
Discourse.git_branch
|
|
||||||
Discourse.full_version
|
|
||||||
|
|
||||||
# V8 does not support forking, make sure all contexts are disposed
|
# V8 does not support forking, make sure all contexts are disposed
|
||||||
ObjectSpace.each_object(MiniRacer::Context) { |c| c.dispose }
|
ObjectSpace.each_object(MiniRacer::Context) { |c| c.dispose }
|
||||||
|
|
||||||
# get rid of rubbish so we don't share it
|
# get rid of rubbish so we don't share it
|
||||||
|
# longer term we will use compact! here
|
||||||
|
GC.start
|
||||||
|
GC.start
|
||||||
GC.start
|
GC.start
|
||||||
|
|
||||||
initialized = true
|
initialized = true
|
||||||
|
|
|
@ -764,4 +764,50 @@ module Discourse
|
||||||
def self.skip_post_deployment_migrations?
|
def self.skip_post_deployment_migrations?
|
||||||
['1', 'true'].include?(ENV["SKIP_POST_DEPLOYMENT_MIGRATIONS"]&.to_s)
|
['1', 'true'].include?(ENV["SKIP_POST_DEPLOYMENT_MIGRATIONS"]&.to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# this is used to preload as much stuff as possible prior to forking
|
||||||
|
# in turn this can conserve large amounts of memory on forking servers
|
||||||
|
def self.preload_rails!
|
||||||
|
return if @preloaded_rails
|
||||||
|
|
||||||
|
# load up all models and schema
|
||||||
|
(ActiveRecord::Base.connection.tables - %w[schema_migrations versions]).each do |table|
|
||||||
|
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
|
||||||
|
I18n.t(:posts)
|
||||||
|
|
||||||
|
# this will force Cppjieba to preload if any site has it
|
||||||
|
# enabled allowing it to be reused between all child processes
|
||||||
|
Search.prepare_data("test")
|
||||||
|
end
|
||||||
|
|
||||||
|
# router warm up
|
||||||
|
Rails.application.routes.recognize_path('abc') rescue nil
|
||||||
|
|
||||||
|
# preload discourse version
|
||||||
|
Discourse.git_version
|
||||||
|
Discourse.git_branch
|
||||||
|
Discourse.full_version
|
||||||
|
|
||||||
|
require 'actionview_precompiler'
|
||||||
|
ActionviewPrecompiler.precompile
|
||||||
|
ensure
|
||||||
|
@preloaded_rails = true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user