Commit 90a57559 authored by Steve Abrams's avatar Steve Abrams

Merge branch '346169_delete_events_in_batches' into 'master'

Delete events in batches when project is destroyed

See merge request gitlab-org/gitlab!77031
parents ea37fafd 7d633be8
...@@ -2,20 +2,29 @@ ...@@ -2,20 +2,29 @@
module Events module Events
class DestroyService class DestroyService
BATCH_SIZE = 50
def initialize(project) def initialize(project)
@project = project @project = project
end end
def execute def execute
project.events.all.delete_all loop do
count = delete_events_in_batches
break if count < BATCH_SIZE
end
ServiceResponse.success(message: 'Events were deleted.') ServiceResponse.success(message: 'Events were deleted.')
rescue StandardError rescue StandardError => e
ServiceResponse.error(message: 'Failed to remove events.') ServiceResponse.error(message: e.message)
end end
private private
attr_reader :project attr_reader :project
def delete_events_in_batches
project.events.limit(BATCH_SIZE).delete_all
end
end end
end end
...@@ -80,8 +80,14 @@ module Projects ...@@ -80,8 +80,14 @@ module Projects
end end
def remove_events def remove_events
log_info("Attempting to destroy events from #{project.full_path} (#{project.id})")
response = ::Events::DestroyService.new(project).execute response = ::Events::DestroyService.new(project).execute
if response.error?
log_error("Event deletion failed on #{project.full_path} with the following message: #{response.message}")
end
response.success? response.success?
end end
......
...@@ -30,16 +30,28 @@ RSpec.describe Events::DestroyService do ...@@ -30,16 +30,28 @@ RSpec.describe Events::DestroyService do
expect(unrelated_event.reload).to be_present expect(unrelated_event.reload).to be_present
end end
context 'batch delete' do
before do
stub_const("#{described_class}::BATCH_SIZE", 2)
end
it 'splits delete queries into batches' do
expect(project).to receive(:events).twice.and_call_original
subject.execute
end
end
context 'when an error is raised while deleting the records' do context 'when an error is raised while deleting the records' do
before do before do
allow(project).to receive_message_chain(:events, :all, :delete_all).and_raise(ActiveRecord::ActiveRecordError) allow(project).to receive_message_chain(:events, :limit, :delete_all).and_raise(ActiveRecord::ActiveRecordError, 'custom error')
end end
it 'returns error' do it 'returns error' do
response = subject.execute response = subject.execute
expect(response).to be_error expect(response).to be_error
expect(response.message).to eq 'Failed to remove events.' expect(response.message).to eq 'custom error'
end end
it 'does not delete events' do it 'does not delete events' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment