Remove rejected and revoked collection items (#38792)

This commit is contained in:
David Roetzel
2026-04-28 13:10:25 +02:00
committed by GitHub
parent d5f8b08d69
commit 1f1653e039
8 changed files with 63 additions and 8 deletions

View File

@@ -51,7 +51,7 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
collection_item = feature_request_from_object
return unless collection_item.account == @account && collection_item.local?
collection_item.destroy!
collection_item.reject!
end
def relay

View File

@@ -25,6 +25,9 @@ class CollectionItem < ApplicationRecord
{ pending: 0, accepted: 1, rejected: 2, revoked: 3 },
validate: true
alias reject! rejected!
alias revoke! revoked!
delegate :local?, :remote?, to: :collection
validates :account_id, uniqueness: { scope: :collection_id }
@@ -45,10 +48,6 @@ class CollectionItem < ApplicationRecord
scope :accepted_partial, ->(account) { joins(:account).merge(Account.local).accepted.where(uri: nil, account_id: account.id) }
scope :pending_or_accepted, -> { where(state: [:pending, :accepted]) }
def revoke!
update!(state: :revoked)
end
def with_local_account?
account&.local?
end

View File

@@ -0,0 +1,16 @@
# frozen_string_literal: true
class Scheduler::CollectionItemCleanupScheduler
include Sidekiq::Worker
RETENTION_PERIOD = 24.hours
sidekiq_options retry: 0, lock: :until_executed, lock_ttl: 1.day.to_i
def perform
CollectionItem
.where(state: [:rejected, :revoked])
.where(updated_at: ...(RETENTION_PERIOD.ago))
.destroy_all
end
end

View File

@@ -72,3 +72,7 @@
interval: 1 day
class: Scheduler::Fasp::FollowRecommendationCleanupScheduler
queue: scheduler
collection_item_cleanup_scheduler:
interval: 1 hour
class: Scheduler::CollectionItemCleanupScheduler
queue: scheduler

View File

@@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddIndexToCollectionItemState < ActiveRecord::Migration[8.1]
disable_ddl_transaction!
def change
add_index :collection_items, :state, where: 'state IN (2, 3)', algorithm: :concurrently
end
end

View File

@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.1].define(version: 2026_04_20_124030) do
ActiveRecord::Schema[8.1].define(version: 2026_04_23_141611) do
# These are extensions that must be enabled in order to support this database
enable_extension "pg_catalog.plpgsql"
@@ -373,6 +373,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_04_20_124030) do
t.index ["account_id", "collection_id"], name: "index_collection_items_on_account_id_and_collection_id", unique: true
t.index ["approval_uri"], name: "index_collection_items_on_approval_uri", unique: true, where: "(approval_uri IS NOT NULL)"
t.index ["collection_id"], name: "index_collection_items_on_collection_id"
t.index ["state"], name: "index_collection_items_on_state", where: "(state = ANY (ARRAY[2, 3]))"
t.index ["uri"], name: "index_collection_items_on_uri", unique: true, where: "(uri IS NOT NULL)"
end

View File

@@ -161,8 +161,11 @@ RSpec.describe ActivityPub::Activity::Reject do
}
end
it 'deletes the collection item' do
expect { subject.perform }.to change(collection.collection_items, :count).by(-1)
it 'sets the collection item state to `rejected`' do
expect do
subject.perform
collection_item.reload
end.to change(collection_item, :state).to('rejected')
end
end
end

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Scheduler::CollectionItemCleanupScheduler do
let(:worker) { described_class.new }
describe '#perform' do
let!(:old_rejected_item) { Fabricate(:collection_item, state: :rejected, updated_at: 25.hours.ago) }
let!(:old_revoked_item) { Fabricate(:collection_item, state: :revoked, updated_at: 26.hours.ago) }
let!(:new_revoked_item) { Fabricate(:collection_item, state: :revoked, updated_at: 2.hours.ago) }
let!(:accepted_item) { Fabricate(:collection_item, state: :accepted, updated_at: 30.hours.ago) }
it 'deletes the rejected and revoked items older than 24 hours' do
expect { subject.perform }.to change(CollectionItem, :count).by(-2)
expect { old_rejected_item.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { old_revoked_item.reload }.to raise_error(ActiveRecord::RecordNotFound)
expect { new_revoked_item.reload }.to_not raise_error
expect { accepted_item.reload }.to_not raise_error
end
end
end