diff options
author | Toon Claes <toon@gitlab.com> | 2017-05-08 17:13:02 +0200 |
---|---|---|
committer | Toon Claes <toon@gitlab.com> | 2017-05-10 15:01:27 +0200 |
commit | 0ad80cab40097658b1eec5b87d440cfcd60d2755 (patch) | |
tree | ac6799f5813de9e0e9c4f584f29f1d9883693d62 /app | |
parent | 4f446dd45a4068a77f606c02c95389c5cf6a6647 (diff) | |
download | gitlab-ce-0ad80cab40097658b1eec5b87d440cfcd60d2755.tar.gz |
Use worker to destroy namespaceless projects in post-deploy
Destroying projects can be very time consuming. So instead of destroying them in
the post-deploy, just schedule them and make Sidekiq do the hard work.
They are scheduled in batches of 5000 records. This way the number of database
requests is limited while also the amount data read to memory is limited.
Diffstat (limited to 'app')
-rw-r--r-- | app/workers/namespaceless_project_destroy_worker.rb | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb new file mode 100644 index 00000000000..da02084c688 --- /dev/null +++ b/app/workers/namespaceless_project_destroy_worker.rb @@ -0,0 +1,46 @@ +# Worker to destroy projects that do not have a namespace +# +# It destroys everything it can without having the info about the namespace it +# used to belong to. Projects in this state should be rare. +# The worker will reject doing anything for projects that *do* have a +# namespace. For those use ProjectDestroyWorker instead. +class NamespacelessProjectDestroyWorker + include Sidekiq::Worker + include DedicatedSidekiqQueue + + def self.bulk_perform_async(args_list) + Sidekiq::Client.push_bulk('class' => self, 'queue' => sidekiq_options['queue'], 'args' => args_list) + end + + def perform(project_id, user_id, params) + begin + project = Project.unscoped.find(project_id) + rescue ActiveRecord::RecordNotFound + return + end + return unless project.namespace_id.nil? # Reject doing anything for projects that *do* have a namespace + + user = User.find(user_id) + return unless user.can?(:remove_project, project) + + project.team.truncate + + unlink_fork(project) if project.forked? + + # Override Project#remove_pages for this instance so it doesn't do anything + def project.remove_pages + end + + project.destroy! + end + + private + + def unlink_fork(project) + merge_requests = project.forked_from_project.merge_requests.opened.from_project(project) + + merge_requests.update_all(state: 'closed') + + project.forked_project_link.destroy + end +end |