diff options
author | Toon Claes <toon@gitlab.com> | 2017-05-08 18:13:02 +0300 |
---|---|---|
committer | Toon Claes <toon@gitlab.com> | 2017-05-10 16:01:27 +0300 |
commit | 0ad80cab40097658b1eec5b87d440cfcd60d2755 (patch) | |
tree | ac6799f5813de9e0e9c4f584f29f1d9883693d62 /db/post_migrate | |
parent | 4f446dd45a4068a77f606c02c95389c5cf6a6647 (diff) |
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 'db/post_migrate')
-rw-r--r-- | db/post_migrate/20170502101023_clean_up_pending_delete_projects.rb | 44 | ||||
-rw-r--r-- | db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb | 50 |
2 files changed, 50 insertions, 44 deletions
diff --git a/db/post_migrate/20170502101023_clean_up_pending_delete_projects.rb b/db/post_migrate/20170502101023_clean_up_pending_delete_projects.rb deleted file mode 100644 index dd812964902..00000000000 --- a/db/post_migrate/20170502101023_clean_up_pending_delete_projects.rb +++ /dev/null @@ -1,44 +0,0 @@ -# See http://doc.gitlab.com/ce/development/migration_style_guide.html -# for more information on how to write migrations for GitLab. - -class CleanUpPendingDeleteProjects < ActiveRecord::Migration - include Gitlab::Database::MigrationHelpers - - DOWNTIME = false - - disable_ddl_transaction! - - def up - Project.unscoped.where(pending_delete: true).each { |project| delete_project(project, admin) } - end - - def down - # noop - end - - private - - def delete_project(project) - project.team.truncate - - unlink_fork(project) if project.forked? - - [:events, :issues, :merge_requests, :labels, :milestones, :notes, :snippets].each do |thing| - project.send(thing).delete_all - end - - # Override Project#remove_pages for this instance so it doesn't do anything - def project.remove_pages - end - - project.destroy! - end - - 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 diff --git a/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb b/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb new file mode 100644 index 00000000000..76ed109898b --- /dev/null +++ b/db/post_migrate/20170502101023_cleanup_namespaceless_pending_delete_projects.rb @@ -0,0 +1,50 @@ +# This is the counterpart of RequeuePendingDeleteProjects and cleans all +# projects with `pending_delete = true` and that do not have a namespace. +class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + admin = User.find_by(admin: true) + return unless admin + + @offset = 0 + + loop do + ids = pending_delete_batch + + break if ids.rows.count.zero? + + args = ids.map { |id| [id['id'], admin.id, {}] } + + NamespacelessProjectDestroyWorker.bulk_perform_async(args) + + @offset += 1 + end + end + + def down + # noop + end + + private + + def pending_delete_batch + connection.exec_query(find_batch) + end + + BATCH_SIZE = 5000 + + def find_batch + projects = Arel::Table.new(:projects) + projects.project(projects[:id]). + where(projects[:pending_delete].eq(true)). + where(projects[:namespace_id].eq(nil)). + skip(@offset * BATCH_SIZE). + take(BATCH_SIZE). + to_sql + end +end |