statuses_vacuum.rb 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. # frozen_string_literal: true
  2. class Vacuum::StatusesVacuum
  3. include Redisable
  4. def initialize(retention_period)
  5. @retention_period = retention_period
  6. end
  7. def perform
  8. vacuum_statuses! if retention_period?
  9. end
  10. private
  11. def vacuum_statuses!
  12. statuses_scope.find_in_batches do |statuses|
  13. # Side-effects not covered by foreign keys, such
  14. # as the search index, must be handled first.
  15. remove_from_account_conversations(statuses)
  16. remove_from_search_index(statuses)
  17. # Foreign keys take care of most associated records
  18. # for us. Media attachments will be orphaned.
  19. Status.where(id: statuses.map(&:id)).delete_all
  20. end
  21. end
  22. def statuses_scope
  23. Status.unscoped.kept.where(account: Account.remote).where(Status.arel_table[:id].lt(retention_period_as_id)).select(:id, :visibility)
  24. end
  25. def retention_period_as_id
  26. Mastodon::Snowflake.id_at(@retention_period.ago, with_random: false)
  27. end
  28. def analyze_statuses!
  29. ActiveRecord::Base.connection.execute('ANALYZE statuses')
  30. end
  31. def remove_from_account_conversations(statuses)
  32. Status.where(id: statuses.select(&:direct_visibility?).map(&:id)).includes(:account, mentions: :account).each(&:unlink_from_conversations)
  33. end
  34. def remove_from_search_index(statuses)
  35. with_redis { |redis| redis.sadd('chewy:queue:StatusesIndex', statuses.map(&:id)) } if Chewy.enabled?
  36. end
  37. def retention_period?
  38. @retention_period.present?
  39. end
  40. end