diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-20 15:19:03 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-20 15:19:03 +0000 |
commit | 14bd84b61276ef29b97d23642d698de769bacfd2 (patch) | |
tree | f9eba90140c1bd874211dea17750a0d422c04080 /app/workers | |
parent | 891c388697b2db0d8ee0c8358a9bdbf6dc56d581 (diff) | |
download | gitlab-ce-14bd84b61276ef29b97d23642d698de769bacfd2.tar.gz |
Add latest changes from gitlab-org/gitlab@15-10-stable-eev15.10.0-rc42
Diffstat (limited to 'app/workers')
38 files changed, 418 insertions, 63 deletions
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index c660243d336..1624538152e 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -5,7 +5,7 @@ --- - :name: authorized_project_update:authorized_project_update_project_recalculate :worker_name: AuthorizedProjectUpdate::ProjectRecalculateWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :high :resource_boundary: :unknown @@ -14,7 +14,7 @@ :tags: [] - :name: authorized_project_update:authorized_project_update_project_recalculate_per_user :worker_name: AuthorizedProjectUpdate::ProjectRecalculatePerUserWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :high :resource_boundary: :unknown @@ -23,7 +23,7 @@ :tags: [] - :name: authorized_project_update:authorized_project_update_user_refresh_from_replica :worker_name: AuthorizedProjectUpdate::UserRefreshFromReplicaWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -32,7 +32,7 @@ :tags: [] - :name: authorized_project_update:authorized_project_update_user_refresh_over_user_range :worker_name: AuthorizedProjectUpdate::UserRefreshOverUserRangeWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -41,7 +41,7 @@ :tags: [] - :name: authorized_project_update:authorized_project_update_user_refresh_with_low_urgency :worker_name: AuthorizedProjectUpdate::UserRefreshWithLowUrgencyWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -617,7 +617,7 @@ :tags: [] - :name: cronjob:personal_access_tokens_expired_notification :worker_name: PersonalAccessTokens::ExpiredNotificationWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -626,7 +626,7 @@ :tags: [] - :name: cronjob:personal_access_tokens_expiring :worker_name: PersonalAccessTokens::ExpiringWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -680,7 +680,7 @@ :tags: [] - :name: cronjob:remove_expired_group_links :worker_name: RemoveExpiredGroupLinksWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -689,7 +689,7 @@ :tags: [] - :name: cronjob:remove_expired_members :worker_name: RemoveExpiredMembersWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :cpu @@ -698,7 +698,7 @@ :tags: [] - :name: cronjob:remove_unaccepted_member_invites :worker_name: RemoveUnacceptedMemberInvitesWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -1137,6 +1137,15 @@ :weight: 1 :idempotent: false :tags: [] +- :name: github_importer:github_import_import_collaborator + :worker_name: Gitlab::GithubImport::ImportCollaboratorWorker + :feature_category: :importers + :has_external_dependencies: true + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: false + :tags: [] - :name: github_importer:github_import_import_diff_note :worker_name: Gitlab::GithubImport::ImportDiffNoteWorker :feature_category: :importers @@ -1272,6 +1281,15 @@ :weight: 1 :idempotent: false :tags: [] +- :name: github_importer:github_import_stage_import_collaborators + :worker_name: Gitlab::GithubImport::Stage::ImportCollaboratorsWorker + :feature_category: :importers + :has_external_dependencies: false + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: false + :tags: [] - :name: github_importer:github_import_stage_import_issue_events :worker_name: Gitlab::GithubImport::Stage::ImportIssueEventsWorker :feature_category: :importers @@ -2165,7 +2183,7 @@ :tags: [] - :name: unassign_issuables:members_destroyer_unassign_issuables :worker_name: MembersDestroyer::UnassignIssuablesWorker - :feature_category: :authentication_and_authorization + :feature_category: :user_management :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2219,7 +2237,7 @@ :tags: [] - :name: authorized_projects :worker_name: AuthorizedProjectsWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :high :resource_boundary: :unknown @@ -2417,7 +2435,7 @@ :tags: [] - :name: delete_user :worker_name: DeleteUserWorker - :feature_category: :authentication_and_authorization + :feature_category: :user_management :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -2611,7 +2629,7 @@ :urgency: :low :resource_boundary: :unknown :weight: 1 - :idempotent: false + :idempotent: true :tags: [] - :name: group_export :worker_name: GroupExportWorker @@ -2642,7 +2660,7 @@ :tags: [] - :name: groups_update_two_factor_requirement_for_members :worker_name: Groups::UpdateTwoFactorRequirementForMembersWorker - :feature_category: :authentication_and_authorization + :feature_category: :system_access :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown @@ -3070,7 +3088,7 @@ :urgency: :low :resource_boundary: :unknown :weight: 1 - :idempotent: false + :idempotent: true :tags: [] - :name: project_export :worker_name: ProjectExportWorker @@ -3108,6 +3126,15 @@ :weight: 1 :idempotent: true :tags: [] +- :name: projects_forks_sync + :worker_name: Projects::Forks::SyncWorker + :feature_category: :source_code_management + :has_external_dependencies: false + :urgency: :high + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: projects_git_garbage_collect :worker_name: Projects::GitGarbageCollectWorker :feature_category: :gitaly @@ -3117,6 +3144,15 @@ :weight: 1 :idempotent: false :tags: [] +- :name: projects_import_export_create_relation_exports + :worker_name: Projects::ImportExport::CreateRelationExportsWorker + :feature_category: :importers + :has_external_dependencies: false + :urgency: :low + :resource_boundary: :cpu + :weight: 1 + :idempotent: true + :tags: [] - :name: projects_import_export_parallel_project_export :worker_name: Projects::ImportExport::ParallelProjectExportWorker :feature_category: :importers @@ -3135,6 +3171,15 @@ :weight: 1 :idempotent: true :tags: [] +- :name: projects_import_export_wait_relation_exports + :worker_name: Projects::ImportExport::WaitRelationExportsWorker + :feature_category: :importers + :has_external_dependencies: false + :urgency: :low + :resource_boundary: :cpu + :weight: 1 + :idempotent: true + :tags: [] - :name: projects_inactive_projects_deletion_notification :worker_name: Projects::InactiveProjectsDeletionNotificationWorker :feature_category: :compliance_management diff --git a/app/workers/authorized_project_update/project_recalculate_per_user_worker.rb b/app/workers/authorized_project_update/project_recalculate_per_user_worker.rb index 352c82e5021..96647cc671c 100644 --- a/app/workers/authorized_project_update/project_recalculate_per_user_worker.rb +++ b/app/workers/authorized_project_update/project_recalculate_per_user_worker.rb @@ -4,7 +4,7 @@ module AuthorizedProjectUpdate class ProjectRecalculatePerUserWorker < ProjectRecalculateWorker data_consistency :always - feature_category :authentication_and_authorization + feature_category :system_access urgency :high queue_namespace :authorized_project_update diff --git a/app/workers/authorized_project_update/project_recalculate_worker.rb b/app/workers/authorized_project_update/project_recalculate_worker.rb index 1b5faee0b6f..cbf068f0b85 100644 --- a/app/workers/authorized_project_update/project_recalculate_worker.rb +++ b/app/workers/authorized_project_update/project_recalculate_worker.rb @@ -9,7 +9,7 @@ module AuthorizedProjectUpdate prepend WaitableWorker - feature_category :authentication_and_authorization + feature_category :system_access urgency :high queue_namespace :authorized_project_update diff --git a/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb b/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb index daebb23baae..cdc0a097c92 100644 --- a/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb +++ b/app/workers/authorized_project_update/user_refresh_from_replica_worker.rb @@ -5,7 +5,7 @@ module AuthorizedProjectUpdate include ApplicationWorker sidekiq_options retry: 3 - feature_category :authentication_and_authorization + feature_category :system_access urgency :low data_consistency :always queue_namespace :authorized_project_update diff --git a/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb b/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb index 8452f2a7821..ae243a94d3d 100644 --- a/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb +++ b/app/workers/authorized_project_update/user_refresh_over_user_range_worker.rb @@ -16,7 +16,7 @@ module AuthorizedProjectUpdate sidekiq_options retry: 3 - feature_category :authentication_and_authorization + feature_category :system_access urgency :low queue_namespace :authorized_project_update diff --git a/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb b/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb index 7ca59a72adf..d6b41ba949c 100644 --- a/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb +++ b/app/workers/authorized_project_update/user_refresh_with_low_urgency_worker.rb @@ -2,7 +2,7 @@ module AuthorizedProjectUpdate class UserRefreshWithLowUrgencyWorker < ::AuthorizedProjectsWorker - feature_category :authentication_and_authorization + feature_category :system_access urgency :low queue_namespace :authorized_project_update deduplicate :until_executing, including_scheduled: true diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb index 4312ba41367..b553a2cd14e 100644 --- a/app/workers/authorized_projects_worker.rb +++ b/app/workers/authorized_projects_worker.rb @@ -8,7 +8,7 @@ class AuthorizedProjectsWorker sidekiq_options retry: 3 prepend WaitableWorker - feature_category :authentication_and_authorization + feature_category :system_access urgency :high weight 2 idempotent! diff --git a/app/workers/ci/archive_traces_cron_worker.rb b/app/workers/ci/archive_traces_cron_worker.rb index fe23d10c2ac..879192e67c4 100644 --- a/app/workers/ci/archive_traces_cron_worker.rb +++ b/app/workers/ci/archive_traces_cron_worker.rb @@ -11,20 +11,12 @@ module Ci feature_category :continuous_integration deduplicate :until_executed, including_scheduled: true - # rubocop: disable CodeReuse/ActiveRecord def perform # Archive stale live traces which still resides in redis or database # This could happen when Ci::ArchiveTraceWorker sidekiq jobs were lost by receiving SIGKILL # More details in https://gitlab.com/gitlab-org/gitlab-foss/issues/36791 - if Feature.enabled?(:deduplicate_archive_traces_cron_worker) - Ci::ArchiveTraceService.new.batch_execute(worker_name: self.class.name) - else - Ci::Build.with_stale_live_trace.find_each(batch_size: 100) do |build| - Ci::ArchiveTraceService.new.execute(build, worker_name: self.class.name) - end - end + Ci::ArchiveTraceService.new.batch_execute(worker_name: self.class.name) end - # rubocop: enable CodeReuse/ActiveRecord end end diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb index e2e31b0a5bd..ce77592daac 100644 --- a/app/workers/concerns/application_worker.rb +++ b/app/workers/concerns/application_worker.rb @@ -11,6 +11,7 @@ module ApplicationWorker include WorkerAttributes include WorkerContext include Gitlab::SidekiqVersioning::Worker + include Gitlab::Loggable LOGGING_EXTRA_KEY = 'extra' SAFE_PUSH_BULK_LIMIT = 1000 @@ -28,7 +29,7 @@ module ApplicationWorker 'jid' => jid ) - payload.stringify_keys.merge(context) + build_structured_payload(**payload).merge(context) end def log_extra_metadata_on_done(key, value) diff --git a/app/workers/concerns/gitlab/github_import/object_importer.rb b/app/workers/concerns/gitlab/github_import/object_importer.rb index c5c7da23892..7e488862696 100644 --- a/app/workers/concerns/gitlab/github_import/object_importer.rb +++ b/app/workers/concerns/gitlab/github_import/object_importer.rb @@ -13,12 +13,27 @@ module Gitlab sidekiq_options retry: 3 include GithubImport::Queue include ReschedulingMethods - include Gitlab::NotifyUponDeath feature_category :importers worker_has_external_dependencies! + + sidekiq_retries_exhausted do |msg| + args = msg['args'] + correlation_id = msg['correlation_id'] + jid = msg['jid'] + + new.perform_failure(args[0], args[1], correlation_id) + + # If a job is being exhausted we still want to notify the + # Gitlab::Import::AdvanceStageWorker to prevent the entire import from getting stuck + if args.length == 3 && (key = args.last) && key.is_a?(String) + JobWaiter.notify(key, jid) + end + end end + NotRetriableError = Class.new(StandardError) + # project - An instance of `Project` to import the data into. # client - An instance of `Gitlab::GithubImport::Client` # hash - A Hash containing the details of the object to import. @@ -47,13 +62,27 @@ module Gitlab # Representation is created but the developer forgot to add a # `:github_identifiers` field. track_and_raise_exception(project, e, fail_import: true) - rescue ActiveRecord::RecordInvalid => e + rescue ActiveRecord::RecordInvalid, NotRetriableError => e # We do not raise exception to prevent job retry - track_exception(project, e) + failure = track_exception(project, e) + add_identifiers_to_failure(failure, object.github_identifiers) rescue StandardError => e track_and_raise_exception(project, e) end + # hash - A Hash containing the details of the object to import. + def perform_failure(project_id, hash, correlation_id) + project = Project.find_by_id(project_id) + return unless project + + failure = project.import_failures.failures_by_correlation_id(correlation_id).first + return unless failure + + object = representation_class.from_json_hash(hash) + + add_identifiers_to_failure(failure, object.github_identifiers) + end + def increment_object_counter?(_object) true end @@ -103,6 +132,10 @@ module Gitlab raise(exception) end + + def add_identifiers_to_failure(failure, external_identifiers) + failure.update_column(:external_identifiers, external_identifiers) + end end end end diff --git a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb index f40855a7455..53e3ac3a1b0 100644 --- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb +++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb @@ -68,7 +68,7 @@ module ContainerExpirationPolicies container_repository_id: repo.id ) - repo.cleanup_ongoing! + repo.start_expiration_policy! end end end @@ -95,10 +95,9 @@ module ContainerExpirationPolicies def cleanup_scheduled_count strong_memoize(:cleanup_scheduled_count) do limit = max_running_jobs + 1 - ContainerExpirationPolicy.with_container_repositories - .runnable_schedules - .limit(limit) - .count + ContainerRepository.requiring_cleanup + .limit(limit) + .count end end diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb index 0af084caf86..bca156ff84c 100644 --- a/app/workers/delete_user_worker.rb +++ b/app/workers/delete_user_worker.rb @@ -7,7 +7,7 @@ class DeleteUserWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :authentication_and_authorization + feature_category :user_management loggable_arguments 2 def perform(current_user_id, delete_user_id, options = {}) diff --git a/app/workers/gitlab/github_import/advance_stage_worker.rb b/app/workers/gitlab/github_import/advance_stage_worker.rb index a9f645bd634..45f4bf486d7 100644 --- a/app/workers/gitlab/github_import/advance_stage_worker.rb +++ b/app/workers/gitlab/github_import/advance_stage_worker.rb @@ -20,6 +20,7 @@ module Gitlab # The known importer stages and their corresponding Sidekiq workers. STAGES = { + collaborators: Stage::ImportCollaboratorsWorker, pull_requests_merged_by: Stage::ImportPullRequestsMergedByWorker, pull_request_review_requests: Stage::ImportPullRequestsReviewRequestsWorker, pull_request_reviews: Stage::ImportPullRequestsReviewsWorker, diff --git a/app/workers/gitlab/github_import/import_collaborator_worker.rb b/app/workers/gitlab/github_import/import_collaborator_worker.rb new file mode 100644 index 00000000000..35cb3fa6830 --- /dev/null +++ b/app/workers/gitlab/github_import/import_collaborator_worker.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Gitlab + module GithubImport + class ImportCollaboratorWorker # rubocop:disable Scalability/IdempotentWorker + include ObjectImporter + + def representation_class + Representation::Collaborator + end + + def importer_class + Importer::CollaboratorImporter + end + + def object_type + :collaborator + end + end + end +end diff --git a/app/workers/gitlab/github_import/stage/import_collaborators_worker.rb b/app/workers/gitlab/github_import/stage/import_collaborators_worker.rb new file mode 100644 index 00000000000..d63d1fd3f5f --- /dev/null +++ b/app/workers/gitlab/github_import/stage/import_collaborators_worker.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +module Gitlab + module GithubImport + module Stage + class ImportCollaboratorsWorker # rubocop:disable Scalability/IdempotentWorker + include ApplicationWorker + + data_consistency :always + + sidekiq_options retry: 3 + include GithubImport::Queue + include StageMethods + + # client - An instance of Gitlab::GithubImport::Client. + # project - An instance of Project. + def import(client, project) + info(project.id, message: 'starting importer', importer: 'Importer::CollaboratorsImporter') + return skip_to_next_stage(project) unless has_push_access?(client, project.import_source) + + waiter = Importer::CollaboratorsImporter.new(project, client).execute + project.import_state.refresh_jid_expiration + + move_to_next_stage(project, { waiter.key => waiter.jobs_remaining }) + rescue StandardError => e + Gitlab::Import::ImportFailureService.track( + project_id: project.id, + error_source: self.class.name, + exception: e, + fail_import: abort_on_failure, + metrics: true + ) + + raise(e) + end + + private + + def has_push_access?(client, repo) + client.repository(repo).dig(:permissions, :push) + end + + def skip_to_next_stage(project) + Gitlab::GithubImport::Logger.warn( + log_attributes( + project.id, + message: 'no push access rights to fetch collaborators', + importer: 'Importer::CollaboratorsImporter' + ) + ) + move_to_next_stage(project, {}) + end + + def move_to_next_stage(project, waiters = {}) + AdvanceStageWorker.perform_async( + project.id, waiters, :pull_requests_merged_by + ) + end + + def abort_on_failure + true + end + end + end + end +end diff --git a/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb b/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb index 71d0247bae0..e7eee0915d5 100644 --- a/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_pull_requests_worker.rb @@ -25,7 +25,7 @@ module Gitlab AdvanceStageWorker.perform_async( project.id, { waiter.key => waiter.jobs_remaining }, - :pull_requests_merged_by + :collaborators ) rescue StandardError => e Gitlab::Import::ImportFailureService.track( diff --git a/app/workers/gitlab/github_import/stage/import_repository_worker.rb b/app/workers/gitlab/github_import/stage/import_repository_worker.rb index 8c1a2cd2677..e13f43ee1f3 100644 --- a/app/workers/gitlab/github_import/stage/import_repository_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_repository_worker.rb @@ -72,7 +72,7 @@ module Gitlab return unless last_github_issue - Issue.track_project_iid!(project, last_github_issue[:number]) + Issue.track_namespace_iid!(project.project_namespace, last_github_issue[:number]) end end end diff --git a/app/workers/gitlab_service_ping_worker.rb b/app/workers/gitlab_service_ping_worker.rb index b02e7318585..53a4361fb48 100644 --- a/app/workers/gitlab_service_ping_worker.rb +++ b/app/workers/gitlab_service_ping_worker.rb @@ -52,3 +52,5 @@ class GitlabServicePingWorker # rubocop:disable Scalability/IdempotentWorker nil end end + +GitlabServicePingWorker.prepend_mod diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb index 92195d3fe16..a116944feb9 100644 --- a/app/workers/group_destroy_worker.rb +++ b/app/workers/group_destroy_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GroupDestroyWorker # rubocop:disable Scalability/IdempotentWorker +class GroupDestroyWorker include ApplicationWorker data_consistency :always @@ -10,6 +10,9 @@ class GroupDestroyWorker # rubocop:disable Scalability/IdempotentWorker feature_category :subgroups + idempotent! + deduplicate :until_executed, ttl: 2.hours + def perform(group_id, user_id) begin group = Group.find(group_id) diff --git a/app/workers/groups/update_two_factor_requirement_for_members_worker.rb b/app/workers/groups/update_two_factor_requirement_for_members_worker.rb index ac1d3589516..ca68a82ec66 100644 --- a/app/workers/groups/update_two_factor_requirement_for_members_worker.rb +++ b/app/workers/groups/update_two_factor_requirement_for_members_worker.rb @@ -9,7 +9,7 @@ module Groups idempotent! - feature_category :authentication_and_authorization + feature_category :system_access def perform(group_id) group = Group.find_by_id(group_id) diff --git a/app/workers/issuable_export_csv_worker.rb b/app/workers/issuable_export_csv_worker.rb index 1c5fab8c4c0..d5e3a86eac1 100644 --- a/app/workers/issuable_export_csv_worker.rb +++ b/app/workers/issuable_export_csv_worker.rb @@ -25,7 +25,13 @@ class IssuableExportCsvWorker # rubocop:disable Scalability/IdempotentWorker def export_service(type, user, project, params) issuable_classes = issuable_classes_for(type.to_sym) issuables = issuable_classes[:finder].new(user, parse_params(params, project.id, type)).execute - issuable_classes[:service].new(issuables, project) + + if type.to_sym == :issue # issues do not support field selection for export + issuable_classes[:service].new(issuables, project, user) + else + fields = params.with_indifferent_access.delete(:selected_fields) || [] + issuable_classes[:service].new(issuables, project, fields) + end end def issuable_classes_for(type) @@ -34,6 +40,8 @@ class IssuableExportCsvWorker # rubocop:disable Scalability/IdempotentWorker { finder: IssuesFinder, service: Issues::ExportCsvService } when :merge_request { finder: MergeRequestsFinder, service: MergeRequests::ExportCsvService } + when :work_item + { finder: WorkItems::WorkItemsFinder, service: WorkItems::ExportCsvService } else raise ArgumentError, type_error_message(type) end @@ -47,7 +55,13 @@ class IssuableExportCsvWorker # rubocop:disable Scalability/IdempotentWorker end def type_error_message(type) - "Type parameter must be :issue or :merge_request, it was #{type}" + types_sentence = allowed_types.to_sentence(last_word_connector: ' or ') + + "Type parameter must be #{types_sentence}, it was #{type}" + end + + def allowed_types + %w[:issue :merge_request :work_item] end end diff --git a/app/workers/issues/placement_worker.rb b/app/workers/issues/placement_worker.rb index ec29a754128..0a4f2612912 100644 --- a/app/workers/issues/placement_worker.rb +++ b/app/workers/issues/placement_worker.rb @@ -40,7 +40,7 @@ module Issues leftover = to_place.pop if to_place.count > QUERY_LIMIT Issue.move_nulls_to_end(to_place) - Issues::BaseService.new(project: nil).rebalance_if_needed(to_place.max_by(&:relative_position)) + Issues::BaseService.new(container: nil).rebalance_if_needed(to_place.max_by(&:relative_position)) Issues::PlacementWorker.perform_async(nil, leftover.project_id) if leftover.present? rescue RelativePositioning::NoSpaceLeft => e Gitlab::ErrorTracking.log_exception(e, issue_id: issue_id, project_id: project_id) diff --git a/app/workers/members_destroyer/unassign_issuables_worker.rb b/app/workers/members_destroyer/unassign_issuables_worker.rb index 915551d6e30..2e6ce0005fc 100644 --- a/app/workers/members_destroyer/unassign_issuables_worker.rb +++ b/app/workers/members_destroyer/unassign_issuables_worker.rb @@ -11,7 +11,7 @@ module MembersDestroyer ENTITY_TYPES = %w(Group Project).freeze queue_namespace :unassign_issuables - feature_category :authentication_and_authorization + feature_category :user_management idempotent! diff --git a/app/workers/new_merge_request_worker.rb b/app/workers/new_merge_request_worker.rb index a32a414c0ba..74239c5d968 100644 --- a/app/workers/new_merge_request_worker.rb +++ b/app/workers/new_merge_request_worker.rb @@ -18,7 +18,6 @@ class NewMergeRequestWorker # rubocop:disable Scalability/IdempotentWorker def perform(merge_request_id, user_id) return unless objects_found?(merge_request_id, user_id) - return if issuable.prepared? MergeRequests::AfterCreateService .new(project: issuable.target_project, current_user: user) diff --git a/app/workers/packages/debian/generate_distribution_worker.rb b/app/workers/packages/debian/generate_distribution_worker.rb index 1eff3ea02dd..f0c753c3a9b 100644 --- a/app/workers/packages/debian/generate_distribution_worker.rb +++ b/app/workers/packages/debian/generate_distribution_worker.rb @@ -20,7 +20,7 @@ module Packages loggable_arguments 0 def perform(container_type, distribution_id) - @container_type = container_type + @container_type = container_type.to_sym @distribution_id = distribution_id return unless distribution diff --git a/app/workers/personal_access_tokens/expired_notification_worker.rb b/app/workers/personal_access_tokens/expired_notification_worker.rb index b119957fa2c..f86bd604cdf 100644 --- a/app/workers/personal_access_tokens/expired_notification_worker.rb +++ b/app/workers/personal_access_tokens/expired_notification_worker.rb @@ -8,7 +8,7 @@ module PersonalAccessTokens include CronjobQueue - feature_category :authentication_and_authorization + feature_category :system_access MAX_TOKENS = 100 diff --git a/app/workers/personal_access_tokens/expiring_worker.rb b/app/workers/personal_access_tokens/expiring_worker.rb index f4afa9f8994..de0bda82573 100644 --- a/app/workers/personal_access_tokens/expiring_worker.rb +++ b/app/workers/personal_access_tokens/expiring_worker.rb @@ -8,7 +8,7 @@ module PersonalAccessTokens include CronjobQueue - feature_category :authentication_and_authorization + feature_category :system_access MAX_TOKENS = 100 diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index f95176da252..676a834d79d 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -140,8 +140,6 @@ class PostReceive end def emit_snowplow_event(project, user) - return unless Feature.enabled?(:route_hll_to_snowplow_phase2, project.namespace) - metric_path = 'counts.source_code_pushes' Gitlab::Tracking.event( 'PostReceive', diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb index 45d0ebd2b65..181eebe56e8 100644 --- a/app/workers/project_destroy_worker.rb +++ b/app/workers/project_destroy_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker +class ProjectDestroyWorker include ApplicationWorker data_consistency :always @@ -10,6 +10,9 @@ class ProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker feature_category :source_code_management + idempotent! + deduplicate :until_executed, ttl: 2.hours + def perform(project_id, user_id, params) project = Project.find(project_id) user = User.find(user_id) diff --git a/app/workers/projects/forks/sync_worker.rb b/app/workers/projects/forks/sync_worker.rb new file mode 100644 index 00000000000..2fa6785bc91 --- /dev/null +++ b/app/workers/projects/forks/sync_worker.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Projects + module Forks + class SyncWorker + include ApplicationWorker + + data_consistency :sticky + idempotent! + urgency :high + feature_category :source_code_management + + def perform(project_id, user_id, ref) + project = Project.find_by_id(project_id) + user = User.find_by_id(user_id) + return unless project && user + + ::Projects::Forks::SyncService.new(project, user, ref).execute + end + end + end +end diff --git a/app/workers/projects/import_export/create_relation_exports_worker.rb b/app/workers/projects/import_export/create_relation_exports_worker.rb new file mode 100644 index 00000000000..9ca69a5500a --- /dev/null +++ b/app/workers/projects/import_export/create_relation_exports_worker.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +module Projects + module ImportExport + class CreateRelationExportsWorker + include ApplicationWorker + include ExceptionBacktrace + + idempotent! + data_consistency :always + deduplicate :until_executed + feature_category :importers + worker_resource_boundary :cpu + sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION + + # This delay is an arbitrary number to finish the export quicker in case all relations + # are exported before the first execution of the WaitRelationExportsWorker worker. + INITIAL_DELAY = 10.seconds + + # rubocop: disable CodeReuse/ActiveRecord + def perform(user_id, project_id, after_export_strategy = {}) + project = Project.find_by_id(project_id) + return unless project + + project_export_job = project.export_jobs.find_or_create_by!(jid: jid) + return if project_export_job.started? + + relation_exports = RelationExport.relation_names_list.map do |relation_name| + project_export_job.relation_exports.find_or_create_by!(relation: relation_name) + end + + relation_exports.each do |relation_export| + RelationExportWorker.with_status.perform_async(relation_export.id) + end + + WaitRelationExportsWorker.perform_in( + INITIAL_DELAY, + project_export_job.id, + user_id, + after_export_strategy + ) + + project_export_job.start! + end + # rubocop: enable CodeReuse/ActiveRecord + end + end +end diff --git a/app/workers/projects/import_export/relation_export_worker.rb b/app/workers/projects/import_export/relation_export_worker.rb index 13ca33c4457..7747d4f4099 100644 --- a/app/workers/projects/import_export/relation_export_worker.rb +++ b/app/workers/projects/import_export/relation_export_worker.rb @@ -10,13 +10,34 @@ module Projects data_consistency :always deduplicate :until_executed feature_category :importers - sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION + sidekiq_options dead: false, status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION urgency :low worker_resource_boundary :memory + sidekiq_retries_exhausted do |job, exception| + relation_export = Projects::ImportExport::RelationExport.find(job['args'].first) + project_export_job = relation_export.project_export_job + project = project_export_job.project + + relation_export.mark_as_failed(job['error_message']) + + log_payload = { + message: 'Project relation export failed', + export_error: job['error_message'], + relation: relation_export.relation, + project_export_job_id: project_export_job.id, + project_name: project.name, + project_id: project.id + } + Gitlab::ExceptionLogFormatter.format!(exception, log_payload) + Gitlab::Export::Logger.error(log_payload) + end + def perform(project_relation_export_id) relation_export = Projects::ImportExport::RelationExport.find(project_relation_export_id) + relation_export.retry! if relation_export.started? + if relation_export.queued? Projects::ImportExport::RelationExportService.new(relation_export, jid).execute end diff --git a/app/workers/projects/import_export/wait_relation_exports_worker.rb b/app/workers/projects/import_export/wait_relation_exports_worker.rb new file mode 100644 index 00000000000..4250073edce --- /dev/null +++ b/app/workers/projects/import_export/wait_relation_exports_worker.rb @@ -0,0 +1,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 diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb index c8dfb2ade0a..927c21d9c53 100644 --- a/app/workers/prune_old_events_worker.rb +++ b/app/workers/prune_old_events_worker.rb @@ -15,9 +15,13 @@ class PruneOldEventsWorker # rubocop:disable Scalability/IdempotentWorker DELETE_LIMIT = 10_000 def perform - # Contribution calendar shows maximum 12 months of events, we retain 3 years for data integrity. - cutoff_date = (3.years + 1.day).ago + if Feature.enabled?(:ops_prune_old_events, type: :ops) + # Contribution calendar shows maximum 12 months of events, we retain 3 years for data integrity. + cutoff_date = (3.years + 1.day).ago - Event.unscoped.created_before(cutoff_date).delete_with_limit(DELETE_LIMIT) + Event.unscoped.created_before(cutoff_date).delete_with_limit(DELETE_LIMIT) + else + Gitlab::AppLogger.info(":ops_prune_old_events is disabled, skipping.") + end end end diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb index 37298c53a5c..f1da5f37945 100644 --- a/app/workers/remove_expired_group_links_worker.rb +++ b/app/workers/remove_expired_group_links_worker.rb @@ -7,7 +7,7 @@ class RemoveExpiredGroupLinksWorker # rubocop:disable Scalability/IdempotentWork include CronjobQueue # rubocop:disable Scalability/CronWorkerContext - feature_category :authentication_and_authorization + feature_category :system_access def perform ProjectGroupLink.expired.find_each do |link| diff --git a/app/workers/remove_expired_members_worker.rb b/app/workers/remove_expired_members_worker.rb index c9eb715a522..b5031f4cda6 100644 --- a/app/workers/remove_expired_members_worker.rb +++ b/app/workers/remove_expired_members_worker.rb @@ -7,7 +7,7 @@ class RemoveExpiredMembersWorker # rubocop:disable Scalability/IdempotentWorker include CronjobQueue - feature_category :authentication_and_authorization + feature_category :system_access worker_resource_boundary :cpu # rubocop: disable CodeReuse/ActiveRecord diff --git a/app/workers/remove_unaccepted_member_invites_worker.rb b/app/workers/remove_unaccepted_member_invites_worker.rb index 7fe45b26094..96f60b5fa12 100644 --- a/app/workers/remove_unaccepted_member_invites_worker.rb +++ b/app/workers/remove_unaccepted_member_invites_worker.rb @@ -7,7 +7,7 @@ class RemoveUnacceptedMemberInvitesWorker # rubocop:disable Scalability/Idempote include CronjobQueue # rubocop:disable Scalability/CronWorkerContext - feature_category :authentication_and_authorization + feature_category :system_access urgency :low idempotent! diff --git a/app/workers/stage_update_worker.rb b/app/workers/stage_update_worker.rb index e0d8958fc80..97da76346b6 100644 --- a/app/workers/stage_update_worker.rb +++ b/app/workers/stage_update_worker.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# This will be scheduled to be removed after removing the FF ci_remove_ensure_stage_service class StageUpdateWorker include ApplicationWorker |