0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-06 13:08:40 +08:00
discourse/spec/lib/site_setting_extension_multisite_spec.rb
Alan Guo Xiang Tan b81b9b8e27
FIX: Refresh site settings after process forks (#41856)
Discourse keeps site settings in memory so it does not need to read them
from the database for every request or job.

Pitchfork starts Sidekiq from a long-running parent process. That parent
can still have the site settings that were loaded when Discourse first
started. When an admin changes a setting, the running Sidekiq process
gets the new value through MessageBus, but the parent can keep the old
value.

If Sidekiq is later restarted, the new Sidekiq process copies the old
settings from its parent. For example, after changing
`site_contact_username`, a restarted Sidekiq process could send system
messages from the previous account. The wrong value remained in use
until another setting changed or Discourse was restarted.

This change reloads site settings from the database after Discourse
starts a new process. It starts listening for new setting changes before
the reload, so a change made during startup is not missed. On multisite
installations, it reloads each site separately.

The reload only updates memory in the new process. It does not clear
shared caches or send another MessageBus message, which avoids extra
work when several processes restart at the same time.
2026-07-22 10:31:05 +08:00

50 lines
1.4 KiB
Ruby
Vendored

# frozen_string_literal: true
RSpec.describe SiteSettingExtension, type: :multisite do
before { MessageBus.off }
after { MessageBus.on }
let(:provider_local) { SiteSettings::LocalProcessProvider.new }
let(:settings) { new_settings(provider_local) }
it "has no db cross talk" do
settings.setting(:hello, 1)
settings.hello = 100
test_multisite_connection("second") { expect(settings.hello).to eq(1) }
end
describe ".after_fork" do
it "loads the current settings for each configured site" do
settings.setting(:hello, 1)
settings.hello = 100
test_multisite_connection("second") { settings.hello = 200 }
settings.provider.save(:hello, 111, SiteSetting.types[:integer])
test_multisite_connection("second") do
settings.provider.save(:hello, 222, SiteSetting.types[:integer])
end
settings.after_fork
expect(settings.hello).to eq(111)
test_multisite_connection("second") { expect(settings.hello).to eq(222) }
end
it "does not publish cache invalidation messages while reloading settings" do
settings.setting(:hello, 1)
settings.hello = 100
settings.provider.save(:hello, 111, SiteSetting.types[:integer])
test_multisite_connection("second") do
settings.provider.save(:hello, 222, SiteSetting.types[:integer])
end
messages = MessageBus.track_publish { settings.after_fork }
expect(messages).to eq([])
end
end
end