Destroy user associations in batches

parent e74f59af
...@@ -20,6 +20,7 @@ class User < ApplicationRecord ...@@ -20,6 +20,7 @@ class User < ApplicationRecord
include WithUploads include WithUploads
include OptionallySearch include OptionallySearch
include FromUnion include FromUnion
include BatchDestroyDependentAssociations
DEFAULT_NOTIFICATION_LEVEL = :participating DEFAULT_NOTIFICATION_LEVEL = :participating
......
...@@ -56,6 +56,13 @@ module Users ...@@ -56,6 +56,13 @@ module Users
MigrateToGhostUserService.new(user).execute unless options[:hard_delete] MigrateToGhostUserService.new(user).execute unless options[:hard_delete]
if Feature.enabled?(:destroy_user_associations_in_batches)
# Rails attempts to load all related records into memory before
# destroying: https://github.com/rails/rails/issues/22510
# This ensures we delete records in batches.
user.destroy_dependent_associations_in_batches
end
# Destroy the namespace after destroying the user since certain methods may depend on the namespace existing # Destroy the namespace after destroying the user since certain methods may depend on the namespace existing
user_data = user.destroy user_data = user.destroy
namespace.destroy namespace.destroy
......
...@@ -20,6 +20,22 @@ describe Users::DestroyService do ...@@ -20,6 +20,22 @@ describe Users::DestroyService do
expect { Namespace.find(namespace.id) }.to raise_error(ActiveRecord::RecordNotFound) expect { Namespace.find(namespace.id) }.to raise_error(ActiveRecord::RecordNotFound)
end end
it 'deletes user associations in batches' do
expect(user).to receive(:destroy_dependent_associations_in_batches)
service.execute(user)
end
context 'when :destroy_user_associations_in_batches flag is disabled' do
it 'does not delete user associations in batches' do
stub_feature_flags(destroy_user_associations_in_batches: false)
expect(user).not_to receive(:destroy_dependent_associations_in_batches)
service.execute(user)
end
end
it 'will delete the project' do it 'will delete the project' do
expect_next_instance_of(Projects::DestroyService) do |destroy_service| expect_next_instance_of(Projects::DestroyService) do |destroy_service|
expect(destroy_service).to receive(:execute).once.and_return(true) expect(destroy_service).to receive(:execute).once.and_return(true)
......
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