2
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-03-04 01:15:08 +08:00
discourse/app/services/upcoming_changes/track.rb
Martin Brennan b8672b3dfb
DEV: Move upcoming change tracking and promotion out of initializers (#37283)
There are several problems with running these upcoming change
checks added in
fb9bb31983:

* The app is slower to boot because there is DB work to be done
* We sometimes swap out database configs at runtime in our hosting,
  which does not call the initializer again
* We have to think about readonly states for the DB
* There are race conditions because of blue-green deployments
  to consider

To solve these problems, we move the tracking and promotion into
a scheduled job that runs every twenty minutes, since the notification
of admins about upcoming changes are not time-sensitive. This avoids
a whole host of problems.

In addition, we are making upcoming change settings declarative
via SiteSettingExtension. Now, instead of actually changing the DB
value of the change when promoting, we just return true for the
setting if it has met the promotion status. However, if admins have
changed the value of the setting in the DB, we do still use that
value instead. Finally we fall back to the default value of the setting.

I've also added a change to track modified site settings. Before this we
had no way to tell if a setting in `current` inside
`SiteSettingExtension`
was modified by an admin or not. This change tracks modified settings in
a new
`modified` object and their values.

---------

Co-authored-by: Loïc Guitaut <loic@discourse.org>
2026-01-30 12:50:39 +10:00

43 lines
1.3 KiB
Ruby

# frozen_string_literal: true
# Handles tracking the addition, removal, and status changes of upcoming changes,
# via UpcomingChangeEvent records, and subsequently notifying admins that the
# upcoming change is available for them to opt-in to, based on certain criteria
# that are explained in the Action classes.
#
# Called from the Jobs::Scheduled::CheckUpcomingChanges job.
class UpcomingChanges::Track
include Service::Base
model :all_admins
model :added_changes, optional: true
model :removed_changes, optional: true
model :status_changes, optional: true
private
def fetch_all_admins
User.human_users.admins
end
def fetch_added_changes(all_admins:)
result = UpcomingChanges::Action::TrackAddedChanges.call(all_admins:)
context[:notified_admins_for_added_changes] = result[:notified_changes]
result[:added_changes]
end
def fetch_removed_changes
UpcomingChanges::Action::TrackRemovedChanges.call
end
def fetch_status_changes(added_changes:, removed_changes:, all_admins:)
result =
UpcomingChanges::Action::TrackStatusChanges.call(
all_admins:,
added_changes:,
removed_changes:,
)
context[:notified_admins_for_added_changes] += result[:notified_changes]
result[:status_changes]
end
end