mirror of
https://github.com/discourse/discourse.git
synced 2026-09-05 04:40:41 -05:00
DEV: Support per-unicorn-worker DB variable overrides (#35615)
This commit adds support for setting ActiveRecord's database configuration variables for unicorn workers via ENVs with the `DISCOURSE_UNICORN_WORKER_DB_VARIABLES_` prefix. For example to set `statement_timeout`, one would add the `DISCOURSE_UNICORN_WORKER_DB_VARIABLES_STATEMENT_TIMEOUT` env with its corresponding value. Do note that envs with the `DISCOURSE_UNICORN_WORKER_DB_VARIABLES_` prefix will take precendent over envs with the `DISCOURSE_DB_VARIABLES_` prefix.
This commit is contained in:
+9
-3
@@ -1,3 +1,10 @@
|
||||
<%
|
||||
db_variables =
|
||||
ENV
|
||||
.filter { |key, _| key.start_with?("DISCOURSE_DB_VARIABLES_") }
|
||||
.transform_keys { |key| key.slice(("DISCOURSE_DB_VARIABLES_".length)..).downcase }
|
||||
%>
|
||||
|
||||
development:
|
||||
prepared_statements: false
|
||||
adapter: postgresql
|
||||
@@ -11,9 +18,7 @@ development:
|
||||
### - restart sidekiq if you change this setting
|
||||
### - rebake all to posts using: `RAILS_ENV=production bundle exec rake posts:rebake`
|
||||
- "<%= ENV['DISCOURSE_HOSTNAME'] || 'localhost' %>"
|
||||
variables: <%= ENV.filter { |k,v| k.start_with? 'DISCOURSE_DB_VARIABLES_' }
|
||||
.transform_keys { |k| k.slice(('DISCOURSE_DB_VARIABLES_'.length)..).downcase }
|
||||
.to_json %>
|
||||
variables: <%= db_variables.to_json %>
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
@@ -41,6 +46,7 @@ test:
|
||||
checkout_timeout: <%= ENV["CHECKOUT_TIMEOUT"] || 5 %>
|
||||
host_names:
|
||||
- test.localhost
|
||||
variables: <%= db_variables.to_json %>
|
||||
|
||||
# profile db is used for benchmarking using the script/bench.rb script
|
||||
profile:
|
||||
|
||||
@@ -194,6 +194,7 @@ end
|
||||
|
||||
after_fork do |server, worker|
|
||||
DiscourseEvent.trigger(:web_fork_started)
|
||||
Discourse.after_unicorn_worker_fork
|
||||
Discourse.after_fork
|
||||
SignalTrapLogger.instance.after_fork
|
||||
|
||||
|
||||
@@ -934,6 +934,26 @@ module Discourse
|
||||
Process.warmup
|
||||
end
|
||||
|
||||
def self.after_unicorn_worker_fork
|
||||
unicorn_worker_db_variables_prefix = "DISCOURSE_UNICORN_WORKER_DB_VARIABLES_"
|
||||
db_variables_overrides = {}
|
||||
|
||||
ENV.filter do |key, value|
|
||||
if key.start_with?(unicorn_worker_db_variables_prefix)
|
||||
db_variables_overrides[
|
||||
"DISCOURSE_DB_VARIABLES_#{key.sub(unicorn_worker_db_variables_prefix, "")}"
|
||||
] = value
|
||||
end
|
||||
end
|
||||
|
||||
if db_variables_overrides.any?
|
||||
db_variables_overrides.each { |key, value| ENV[key] = value }
|
||||
ActiveRecord::Base.configurations = Rails.application.config.database_configuration
|
||||
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
||||
ActiveRecord::Base.establish_connection
|
||||
end
|
||||
end
|
||||
|
||||
# all forking servers must call this
|
||||
# after fork, otherwise Discourse will be
|
||||
# in a bad state
|
||||
|
||||
@@ -67,6 +67,41 @@ RSpec.describe Discourse do
|
||||
end
|
||||
end
|
||||
|
||||
describe ".after_unicorn_worker_fork" do
|
||||
around do |example|
|
||||
original_env = ENV.to_hash
|
||||
original_config = ActiveRecord::Base.configurations
|
||||
original_show_statement_timeout =
|
||||
ActiveRecord::Base.connection.execute("SHOW statement_timeout").first["statement_timeout"]
|
||||
|
||||
begin
|
||||
example.run
|
||||
ensure
|
||||
ENV.replace(original_env)
|
||||
ActiveRecord::Base.configurations = original_config
|
||||
ActiveRecord::Base.connection_handler.clear_all_connections!(:all)
|
||||
ActiveRecord::Base.establish_connection
|
||||
|
||||
expect(
|
||||
ActiveRecord::Base.connection.execute("SHOW statement_timeout").first[
|
||||
"statement_timeout"
|
||||
],
|
||||
).to eq(original_show_statement_timeout)
|
||||
end
|
||||
end
|
||||
|
||||
it "applies worker-specific database variable overrides" do
|
||||
ENV["DISCOURSE_DB_VARIABLES_STATEMENT_TIMEOUT"] = "5s"
|
||||
ENV["DISCOURSE_UNICORN_WORKER_DB_VARIABLES_STATEMENT_TIMEOUT"] = "100s"
|
||||
|
||||
Discourse.after_unicorn_worker_fork
|
||||
|
||||
expect(
|
||||
ActiveRecord::Base.connection.execute("SHOW statement_timeout").first["statement_timeout"],
|
||||
).to eq("100s")
|
||||
end
|
||||
end
|
||||
|
||||
describe ".plugins_sorted_by_name" do
|
||||
before do
|
||||
Discourse.stubs(:visible_plugins).returns(
|
||||
|
||||
Reference in New Issue
Block a user