Welcome to mirror list, hosted at ThFree Co, Russian Federation.

wait_relation_exports_worker.rb « import_export « projects « workers « app - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 4250073edcee3e1e7038f91eb22989b16414cdb3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# frozen_string_literal: true

module Projects
  module ImportExport
    class WaitRelationExportsWorker
      include ApplicationWorker
      include ExceptionBacktrace

      idempotent!
      data_consistency :always
      deduplicate :until_executed
      feature_category :importers
      loggable_arguments 1, 2
      worker_resource_boundary :cpu
      sidekiq_options dead: false, status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION

      INTERVAL = 1.minute

      def perform(project_export_job_id, user_id, after_export_strategy = {})
        @export_job = ProjectExportJob.find(project_export_job_id)

        return unless @export_job.started?

        @export_job.update_attribute(:jid, jid)
        @relation_exports = @export_job.relation_exports

        if queued_relation_exports.any? || started_relation_exports.any?
          fail_started_jobs_no_longer_running

          self.class.perform_in(INTERVAL, project_export_job_id, user_id, after_export_strategy)
          return
        end

        if all_relation_export_finished?
          ParallelProjectExportWorker.perform_async(project_export_job_id, user_id, after_export_strategy)
          return
        end

        fail_and_notify_user(user_id)
      end

      private

      def relation_exports_with_status(status)
        @relation_exports.select { |relation_export| relation_export.status == status }
      end

      def queued_relation_exports
        relation_exports_with_status(RelationExport::STATUS[:queued])
      end

      def started_relation_exports
        @started_relation_exports ||= relation_exports_with_status(RelationExport::STATUS[:started])
      end

      def all_relation_export_finished?
        @relation_exports.all? { |relation_export| relation_export.status == RelationExport::STATUS[:finished] }
      end

      def fail_started_jobs_no_longer_running
        started_relation_exports.each do |relation_export|
          next if Gitlab::SidekiqStatus.running?(relation_export.jid)
          next if relation_export.reset.finished?

          relation_export.mark_as_failed("Exausted number of retries to export: #{relation_export.relation}")
        end
      end

      def fail_and_notify_user(user_id)
        @export_job.fail_op!

        @user = User.find_by_id(user_id)
        return unless @user

        failed_relation_exports = relation_exports_with_status(RelationExport::STATUS[:failed])
        errors = failed_relation_exports.map(&:export_error)

        NotificationService.new.project_not_exported(@export_job.project, @user, errors)
      end
    end
  end
end