Minor clean up and optimization of the automatic post deletion code (#24613)

This commit is contained in:
Claire 2023-04-21 16:53:50 +02:00 committed by GitHub
parent 88ce59505e
commit b0eba1a060
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -57,9 +57,9 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
before_save :update_last_inspected before_save :update_last_inspected
def statuses_to_delete(limit = 50, max_id = nil, min_id = nil) def statuses_to_delete(limit = 50, max_id = nil, min_id = nil)
scope = account.statuses scope = account_statuses
scope.merge!(old_enough_scope(max_id)) scope.merge!(old_enough_scope(max_id))
scope = scope.where(Status.arel_table[:id].gteq(min_id)) if min_id.present? scope = scope.where(id: min_id..) if min_id.present?
scope.merge!(without_popular_scope) unless min_favs.nil? && min_reblogs.nil? scope.merge!(without_popular_scope) unless min_favs.nil? && min_reblogs.nil?
scope.merge!(without_direct_scope) if keep_direct? scope.merge!(without_direct_scope) if keep_direct?
scope.merge!(without_pinned_scope) if keep_pinned? scope.merge!(without_pinned_scope) if keep_pinned?
@ -80,7 +80,7 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
def compute_cutoff_id def compute_cutoff_id
min_id = last_inspected || 0 min_id = last_inspected || 0
max_id = Mastodon::Snowflake.id_at(min_status_age.seconds.ago, with_random: false) max_id = Mastodon::Snowflake.id_at(min_status_age.seconds.ago, with_random: false)
subquery = account.statuses.where(Status.arel_table[:id].gteq(min_id)).where(Status.arel_table[:id].lteq(max_id)) subquery = account_statuses.where(id: min_id..max_id)
subquery = subquery.select(:id).reorder(id: :asc).limit(EARLY_SEARCH_CUTOFF) subquery = subquery.select(:id).reorder(id: :asc).limit(EARLY_SEARCH_CUTOFF)
# We're textually interpolating a subquery here as ActiveRecord seem to not provide # We're textually interpolating a subquery here as ActiveRecord seem to not provide
@ -91,11 +91,11 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
# The most important thing about `last_inspected` is that any toot older than it is guaranteed # The most important thing about `last_inspected` is that any toot older than it is guaranteed
# not to be kept by the policy regardless of its age. # not to be kept by the policy regardless of its age.
def record_last_inspected(last_id) def record_last_inspected(last_id)
redis.set("account_cleanup:#{account.id}", last_id, ex: 1.week.seconds) redis.set("account_cleanup:#{account_id}", last_id, ex: 2.weeks.seconds)
end end
def last_inspected def last_inspected
redis.get("account_cleanup:#{account.id}")&.to_i redis.get("account_cleanup:#{account_id}")&.to_i
end end
def invalidate_last_inspected(status, action) def invalidate_last_inspected(status, action)
@ -120,9 +120,9 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
if EXCEPTION_BOOLS.map { |name| attribute_change_to_be_saved(name) }.compact.include?([true, false]) if EXCEPTION_BOOLS.map { |name| attribute_change_to_be_saved(name) }.compact.include?([true, false])
# Policy has been widened in such a way that any previously-inspected status # Policy has been widened in such a way that any previously-inspected status
# may need to be deleted, so we'll have to start again. # may need to be deleted, so we'll have to start again.
redis.del("account_cleanup:#{account.id}") redis.del("account_cleanup:#{account_id}")
end end
redis.del("account_cleanup:#{account.id}") if EXCEPTION_THRESHOLDS.map { |name| attribute_change_to_be_saved(name) }.compact.any? { |old, new| old.present? && (new.nil? || new > old) } redis.del("account_cleanup:#{account_id}") if EXCEPTION_THRESHOLDS.map { |name| attribute_change_to_be_saved(name) }.compact.any? { |old, new| old.present? && (new.nil? || new > old) }
end end
def validate_local_account def validate_local_account
@ -141,23 +141,23 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
max_id = snowflake_id if max_id.nil? || snowflake_id < max_id max_id = snowflake_id if max_id.nil? || snowflake_id < max_id
Status.where(Status.arel_table[:id].lteq(max_id)) Status.where(id: ..max_id)
end end
def without_self_fav_scope def without_self_fav_scope
Status.where('NOT EXISTS (SELECT * FROM favourites fav WHERE fav.account_id = statuses.account_id AND fav.status_id = statuses.id)') Status.where('NOT EXISTS (SELECT 1 FROM favourites fav WHERE fav.account_id = statuses.account_id AND fav.status_id = statuses.id)')
end end
def without_self_bookmark_scope def without_self_bookmark_scope
Status.where('NOT EXISTS (SELECT * FROM bookmarks bookmark WHERE bookmark.account_id = statuses.account_id AND bookmark.status_id = statuses.id)') Status.where('NOT EXISTS (SELECT 1 FROM bookmarks bookmark WHERE bookmark.account_id = statuses.account_id AND bookmark.status_id = statuses.id)')
end end
def without_pinned_scope def without_pinned_scope
Status.where('NOT EXISTS (SELECT * FROM status_pins pin WHERE pin.account_id = statuses.account_id AND pin.status_id = statuses.id)') Status.where('NOT EXISTS (SELECT 1 FROM status_pins pin WHERE pin.account_id = statuses.account_id AND pin.status_id = statuses.id)')
end end
def without_media_scope def without_media_scope
Status.where('NOT EXISTS (SELECT * FROM media_attachments media WHERE media.status_id = statuses.id)') Status.where('NOT EXISTS (SELECT 1 FROM media_attachments media WHERE media.status_id = statuses.id)')
end end
def without_poll_scope def without_poll_scope
@ -170,4 +170,8 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
scope = scope.where('COALESCE(status_stats.favourites_count, 0) < ?', min_favs) unless min_favs.nil? scope = scope.where('COALESCE(status_stats.favourites_count, 0) < ?', min_favs) unless min_favs.nil?
scope scope
end end
def account_statuses
Status.where(account_id: account_id)
end
end end