New service to retry failed placeholder assignments

What does this MR do and why?

When a placeholder user reassignment fails after an import, the Import::SourceUser record gets stuck in a FAILED status with no way to retry or recover. This MR adds a new service that allows top-level group owners to retry failed placeholder reassignments as part of implementing a "retry" action.

A new GraphQL mutation to call this service will be implemented in a subsequent MR and no other components call the new service yet. This MR is part of the implementation of #589777

References

How to set up and validate locally

Because nothing calls this service, validate by checking that specs pass and the service performs as expected in the console:

  1. Find or create an import source user (placeholder user) by running an import from any of the supported importers. Do not import a project into a personal namespace because it will assign all contributions directly to the personal namespace's user. You can also create an Import::SourceUser in the console, but I recommend performing an import to simulate a real failure with user contributions
  2. Once the import finishes, make it so that the initial reassignment attempt fails. Manually raising an error is the most straightforward way to guarantee it. Something like this should simulate the bug that led to this MR's issue:
diff --git a/app/services/import/reassign_placeholder_user_records_service.rb b/app/services/import/reassign_placeholder_user_records_service.rb
index bf7fdf2ca26669..7a2597b045e82c 100644
--- a/app/services/import/reassign_placeholder_user_records_service.rb
+++ b/app/services/import/reassign_placeholder_user_records_service.rb
@@ -31,6 +31,7 @@ def execute
 
         reassign_placeholder_references
 
+        raise StandardError, 'Break before reassigning memberships'
         delete_remaining_references
 
         if placeholder_memberships.any?
diff --git a/app/workers/import/reassign_placeholder_user_records_worker.rb b/app/workers/import/reassign_placeholder_user_records_worker.rb
index b1294989ee8a73..df7bc18678cc2b 100644
--- a/app/workers/import/reassign_placeholder_user_records_worker.rb
+++ b/app/workers/import/reassign_placeholder_user_records_worker.rb
@@ -11,7 +11,7 @@ class ReassignPlaceholderUserRecordsWorker
     data_consistency :sticky
     feature_category :importers
     deduplicate :until_executed
-    sidekiq_options retry: 5, dead: false
+    sidekiq_options retry: 1, dead: false
     sidekiq_options max_retries_after_interruption: 20
     concurrency_limit -> { 4 }
  1. Assign a real user to the source user and accept the assignment.
  2. Accepting the reassignment begins the backend process to reassign all imported records to the real user. The exception added in step 2 should be thrown and cause the reassignment to fail. Allow the async worker to finish.
  3. Set reassignment_error on the failed source user to anything in the console if !227775 (merged) hasn't been merged (optional)
  4. Remove the manual failure in ReassignPlaceholderUserRecordsWorker and/or ReassignPlaceholderUserRecordsService
  5. Initialize and execute Import::SourceUsers::RetryFailedReassignmentService with the failed source user and an owner on the source user's namespace
  6. Verify the source user is returned in the response and it's in reassignment_in_progress (2) status
  7. Verify the retried source user eventually completes and its user contributions are reassigned

Additional validations on the service:

  • Only owners of the top-level namespace can retry failed source users. I.e. current_user must be able to admin_import_source_user, which is enabled when they can admin_namespace on the source user's namespace
  • The source user must be failed, no other statuses are allowed to retry

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to #589777

Edited by Sam Word

Merge request reports

Loading