FEATURE: limit number of notifications per user to 10,000

Introduces a new site setting `max_notifications_per_user`.

Out-of-the-box this is set to 10,000. If a user exceeds this number of
notifications, we will delete the oldest notifications keeping only 10,000.

To disable this safeguard set the setting to 0.

Enforcement happens weekly.

This is in place to protect the system from pathological states where a
single user has enormous amounts of notifications causing various queries
to time out. In practice nobody looks back more than a few hundred notifications.
This commit is contained in:
Sam Saffron
2020-02-24 11:42:50 +11:00
parent f93de763b7
commit 372f6f4f22
5 changed files with 46 additions and 0 deletions

View File

@@ -44,6 +44,25 @@ class Notification < ActiveRecord::Base
send_email unless NotificationConsolidator.new(self).consolidate!
end
def self.purge_old!
return if SiteSetting.max_notifications_per_user == 0
DB.exec(<<~SQL, SiteSetting.max_notifications_per_user)
DELETE FROM notifications n1
USING (
SELECT * FROM (
SELECT
user_id,
id,
rank() OVER (PARTITION BY user_id ORDER BY id DESC)
FROM notifications
) AS X
WHERE rank = ?
) n2
WHERE n1.user_id = n2.user_id AND n1.id < n2.id
SQL
end
def self.ensure_consistency!
DB.exec(<<~SQL, Notification.types[:private_message])
DELETE