diff --git a/app/services/bulk_imports/relation_export_service.rb b/app/services/bulk_imports/relation_export_service.rb index 14f073120c5d181dbbb6c7411a5fab9da14e4c76..c43f0d8cb4fa389c7340b62615598f156f57a992 100644 --- a/app/services/bulk_imports/relation_export_service.rb +++ b/app/services/bulk_imports/relation_export_service.rb @@ -4,6 +4,8 @@ module BulkImports class RelationExportService include Gitlab::ImportExport::CommandLineUtil + EXISTING_EXPORT_TTL = 3.minutes + def initialize(user, portable, relation, jid) @user = user @portable = portable @@ -31,6 +33,9 @@ def find_or_create_export! validate_user_permissions! export = portable.bulk_import_exports.safe_find_or_create_by!(relation: relation) + + return export if export.finished? && export.updated_at > EXISTING_EXPORT_TTL.ago + export.update!(status_event: 'start', jid: jid) yield export diff --git a/app/workers/bulk_imports/relation_export_worker.rb b/app/workers/bulk_imports/relation_export_worker.rb index 9324b79cc753f90201676ff134f663db97e71f7b..dcac841b3b2f5820b502699273dca20504bc2b80 100644 --- a/app/workers/bulk_imports/relation_export_worker.rb +++ b/app/workers/bulk_imports/relation_export_worker.rb @@ -3,12 +3,12 @@ module BulkImports class RelationExportWorker include ApplicationWorker - - data_consistency :always include ExceptionBacktrace idempotent! + deduplicate :until_executed loggable_arguments 2, 3 + data_consistency :always feature_category :importers sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION diff --git a/spec/services/bulk_imports/relation_export_service_spec.rb b/spec/services/bulk_imports/relation_export_service_spec.rb index 27a6ca605153cca725cad0ddf26331421215fd6e..f0f85217d2ea1e1f187661c6761b5a84f1b7bddc 100644 --- a/spec/services/bulk_imports/relation_export_service_spec.rb +++ b/spec/services/bulk_imports/relation_export_service_spec.rb @@ -88,6 +88,18 @@ subject.execute end + + context 'when export is recently finished' do + it 'returns recently finished export instead of re-exporting' do + updated_at = 5.seconds.ago + export.update!(status: 1, updated_at: updated_at) + + expect { subject.execute }.not_to change { export.updated_at } + + expect(export.status).to eq(1) + expect(export.updated_at).to eq(updated_at) + end + end end context 'when exception occurs during export' do