diff options
Diffstat (limited to 'app/workers')
72 files changed, 591 insertions, 186 deletions
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index c7ce2eb8d00..699744b355c 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -246,6 +246,15 @@ :weight: 1 :idempotent: true :tags: [] +- :name: cronjob:clusters_integrations_check_prometheus_health + :worker_name: Clusters::Integrations::CheckPrometheusHealthWorker + :feature_category: :incident_management + :has_external_dependencies: true + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: cronjob:container_expiration_policy :worker_name: ContainerExpirationPolicyWorker :feature_category: :container_registry @@ -347,13 +356,22 @@ :tags: [] - :name: cronjob:issue_due_scheduler :worker_name: IssueDueSchedulerWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown :weight: 1 :idempotent: :tags: [] +- :name: cronjob:issues_reschedule_stuck_issue_rebalances + :worker_name: Issues::RescheduleStuckIssueRebalancesWorker + :feature_category: :team_planning + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: cronjob:jira_import_stuck_jira_import_jobs :worker_name: Gitlab::JiraImport::StuckJiraImportJobsWorker :feature_category: :importers @@ -363,6 +381,15 @@ :weight: 1 :idempotent: :tags: [] +- :name: cronjob:loose_foreign_keys_cleanup + :worker_name: LooseForeignKeys::CleanupWorker + :feature_category: :sharding + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: cronjob:member_invitation_reminder_emails :worker_name: MemberInvitationReminderEmailsWorker :feature_category: :subgroups @@ -696,6 +723,15 @@ :weight: 1 :idempotent: true :tags: [] +- :name: deployment:deployments_archive_in_project + :worker_name: Deployments::ArchiveInProjectWorker + :feature_category: :continuous_delivery + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 3 + :idempotent: true + :tags: [] - :name: deployment:deployments_drop_older_deployments :worker_name: Deployments::DropOlderDeploymentsWorker :feature_category: :continuous_delivery @@ -1069,15 +1105,6 @@ :idempotent: :tags: - :needs_own_queue -- :name: incident_management:clusters_applications_check_prometheus_health - :worker_name: Clusters::Applications::CheckPrometheusHealthWorker - :feature_category: :incident_management - :has_external_dependencies: true - :urgency: :low - :resource_boundary: :unknown - :weight: 2 - :idempotent: true - :tags: [] - :name: incident_management:incident_management_add_severity_system_note :worker_name: IncidentManagement::AddSeveritySystemNoteWorker :feature_category: :incident_management @@ -1251,7 +1278,7 @@ :tags: [] - :name: mail_scheduler:mail_scheduler_issue_due :worker_name: MailScheduler::IssueDueWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1260,7 +1287,7 @@ :tags: [] - :name: mail_scheduler:mail_scheduler_notification_service :worker_name: MailScheduler::NotificationServiceWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :cpu @@ -1737,7 +1764,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_confidential_issue :worker_name: TodosDestroyer::ConfidentialIssueWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1746,7 +1773,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_destroyed_designs :worker_name: TodosDestroyer::DestroyedDesignsWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1755,7 +1782,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_destroyed_issuable :worker_name: TodosDestroyer::DestroyedIssuableWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1764,7 +1791,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_entity_leave :worker_name: TodosDestroyer::EntityLeaveWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1773,7 +1800,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_group_private :worker_name: TodosDestroyer::GroupPrivateWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1782,7 +1809,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_private_features :worker_name: TodosDestroyer::PrivateFeaturesWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -1791,7 +1818,7 @@ :tags: [] - :name: todos_destroyer:todos_destroyer_project_private :worker_name: TodosDestroyer::ProjectPrivateWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -2052,7 +2079,7 @@ :tags: [] - :name: email_receiver :worker_name: EmailReceiverWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :high :resource_boundary: :unknown @@ -2116,7 +2143,7 @@ :tags: [] - :name: export_csv :worker_name: ExportCsvWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :cpu @@ -2206,13 +2233,22 @@ :tags: [] - :name: import_issues_csv :worker_name: ImportIssuesCsvWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :cpu :weight: 2 :idempotent: true :tags: [] +- :name: integrations_create_external_cross_reference + :worker_name: Integrations::CreateExternalCrossReferenceWorker + :feature_category: :integrations + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] - :name: invalid_gpg_signature_update :worker_name: InvalidGpgSignatureUpdateWorker :feature_category: :source_code_management @@ -2233,7 +2269,7 @@ :tags: [] - :name: issuable_export_csv :worker_name: IssuableExportCsvWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :cpu @@ -2242,7 +2278,7 @@ :tags: [] - :name: issuable_label_links_destroy :worker_name: Issuable::LabelLinksDestroyWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -2251,7 +2287,7 @@ :tags: [] - :name: issuables_clear_groups_issue_counter :worker_name: Issuables::ClearGroupsIssueCounterWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -2260,7 +2296,7 @@ :tags: [] - :name: issue_placement :worker_name: IssuePlacementWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :high :resource_boundary: :cpu @@ -2269,7 +2305,25 @@ :tags: [] - :name: issue_rebalancing :worker_name: IssueRebalancingWorker - :feature_category: :issue_tracking + :feature_category: :team_planning + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: true + :tags: [] +- :name: issues_placement + :worker_name: Issues::PlacementWorker + :feature_category: :team_planning + :has_external_dependencies: + :urgency: :high + :resource_boundary: :cpu + :weight: 2 + :idempotent: true + :tags: [] +- :name: issues_rebalancing + :worker_name: Issues::RebalancingWorker + :feature_category: :team_planning :has_external_dependencies: :urgency: :low :resource_boundary: :unknown @@ -2375,6 +2429,15 @@ :weight: 1 :idempotent: :tags: [] +- :name: namespaces_invite_team_email + :worker_name: Namespaces::InviteTeamEmailWorker + :feature_category: :experimentation_activation + :has_external_dependencies: + :urgency: :low + :resource_boundary: :unknown + :weight: 1 + :idempotent: + :tags: [] - :name: namespaces_onboarding_issue_created :worker_name: Namespaces::OnboardingIssueCreatedWorker :feature_category: :onboarding @@ -2413,7 +2476,7 @@ :tags: [] - :name: new_issue :worker_name: NewIssueWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :high :resource_boundary: :cpu @@ -2431,7 +2494,7 @@ :tags: [] - :name: new_note :worker_name: NewNoteWorker - :feature_category: :issue_tracking + :feature_category: :team_planning :has_external_dependencies: :urgency: :high :resource_boundary: :cpu @@ -2799,6 +2862,15 @@ :weight: 1 :idempotent: :tags: [] +- :name: tasks_to_be_done_create + :worker_name: TasksToBeDone::CreateWorker + :feature_category: :onboarding + :has_external_dependencies: + :urgency: :low + :resource_boundary: :cpu + :weight: 1 + :idempotent: true + :tags: [] - :name: update_external_pull_requests :worker_name: UpdateExternalPullRequestsWorker :feature_category: :source_code_management diff --git a/app/workers/authorized_project_update/project_recalculate_worker.rb b/app/workers/authorized_project_update/project_recalculate_worker.rb index 3d073f18622..1b5faee0b6f 100644 --- a/app/workers/authorized_project_update/project_recalculate_worker.rb +++ b/app/workers/authorized_project_update/project_recalculate_worker.rb @@ -7,6 +7,8 @@ module AuthorizedProjectUpdate data_consistency :always include Gitlab::ExclusiveLeaseHelpers + prepend WaitableWorker + feature_category :authentication_and_authorization urgency :high queue_namespace :authorized_project_update diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb index 46fe6c7f7ce..afe14369d43 100644 --- a/app/workers/authorized_projects_worker.rb +++ b/app/workers/authorized_projects_worker.rb @@ -25,11 +25,9 @@ class AuthorizedProjectsWorker end end - # rubocop: disable CodeReuse/ActiveRecord def perform(user_id) - user = User.find_by(id: user_id) + user = User.find_by_id(user_id) user&.refresh_authorized_projects(source: self.class.name) end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index a0d1d9dca45..78244e0941e 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -14,7 +14,7 @@ class BuildHooksWorker # rubocop:disable Scalability/IdempotentWorker # rubocop: disable CodeReuse/ActiveRecord def perform(build_id) Ci::Build.includes({ runner: :tags }) - .find_by(id: build_id) + .find_by_id(build_id) .try(:execute_hooks) end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/workers/build_queue_worker.rb b/app/workers/build_queue_worker.rb index 4ab08bbd7fe..af1136de94c 100644 --- a/app/workers/build_queue_worker.rb +++ b/app/workers/build_queue_worker.rb @@ -12,11 +12,9 @@ class BuildQueueWorker # rubocop:disable Scalability/IdempotentWorker worker_resource_boundary :cpu data_consistency :sticky - # rubocop: disable CodeReuse/ActiveRecord def perform(build_id) - Ci::Build.find_by(id: build_id).try do |build| + Ci::Build.find_by_id(build_id).try do |build| Ci::UpdateBuildQueueService.new.tick(build) end end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb index ce39ac946a9..114bced0b22 100644 --- a/app/workers/build_success_worker.rb +++ b/app/workers/build_success_worker.rb @@ -11,13 +11,11 @@ class BuildSuccessWorker # rubocop:disable Scalability/IdempotentWorker queue_namespace :pipeline_processing urgency :high - # rubocop: disable CodeReuse/ActiveRecord def perform(build_id) - Ci::Build.find_by(id: build_id).try do |build| + Ci::Build.find_by_id(build_id).try do |build| stop_environment(build) if build.stops_environment? end end - # rubocop: enable CodeReuse/ActiveRecord private diff --git a/app/workers/chat_notification_worker.rb b/app/workers/chat_notification_worker.rb index 2a2e94cc6f1..23d8a1ec29d 100644 --- a/app/workers/chat_notification_worker.rb +++ b/app/workers/chat_notification_worker.rb @@ -16,9 +16,8 @@ class ChatNotificationWorker # rubocop:disable Scalability/IdempotentWorker RESCHEDULE_INTERVAL = 2.seconds RESCHEDULE_TIMEOUT = 5.minutes - # rubocop: disable CodeReuse/ActiveRecord def perform(build_id, reschedule_count = 0) - Ci::Build.find_by(id: build_id).try do |build| + Ci::Build.find_by_id(build_id).try do |build| send_response(build) end rescue Gitlab::Chat::Output::MissingBuildSectionError @@ -30,7 +29,6 @@ class ChatNotificationWorker # rubocop:disable Scalability/IdempotentWorker # the job instead of producing an error. self.class.perform_in(RESCHEDULE_INTERVAL, build_id, reschedule_count + 1) end - # rubocop: enable CodeReuse/ActiveRecord def send_response(build) Gitlab::Chat::Responder.responder_for(build).try do |responder| diff --git a/app/workers/ci/archive_trace_worker.rb b/app/workers/ci/archive_trace_worker.rb index 503cfc07c25..5a22a5c74ee 100644 --- a/app/workers/ci/archive_trace_worker.rb +++ b/app/workers/ci/archive_trace_worker.rb @@ -9,12 +9,10 @@ module Ci sidekiq_options retry: 3 include PipelineBackgroundQueue - # rubocop: disable CodeReuse/ActiveRecord def perform(job_id) - Ci::Build.without_archived_trace.find_by(id: job_id).try do |job| + Ci::Build.without_archived_trace.find_by_id(job_id).try do |job| Ci::ArchiveTraceService.new.execute(job, worker_name: self.class.name) end end - # rubocop: enable CodeReuse/ActiveRecord end end diff --git a/app/workers/ci/build_finished_worker.rb b/app/workers/ci/build_finished_worker.rb index f047ba8fde5..aa12bdb009e 100644 --- a/app/workers/ci/build_finished_worker.rb +++ b/app/workers/ci/build_finished_worker.rb @@ -16,7 +16,7 @@ module Ci ARCHIVE_TRACES_IN = 2.minutes.freeze def perform(build_id) - return unless build = Ci::Build.find_by(id: build_id) # rubocop: disable CodeReuse/ActiveRecord + return unless build = Ci::Build.find_by_id(build_id) return unless build.project return if build.project.pending_delete? diff --git a/app/workers/ci/build_trace_chunk_flush_worker.rb b/app/workers/ci/build_trace_chunk_flush_worker.rb index 79881ec84fd..62fc3efd4f0 100644 --- a/app/workers/ci/build_trace_chunk_flush_worker.rb +++ b/app/workers/ci/build_trace_chunk_flush_worker.rb @@ -13,12 +13,10 @@ module Ci idempotent! - # rubocop: disable CodeReuse/ActiveRecord def perform(id) - ::Ci::BuildTraceChunk.find_by(id: id).try do |chunk| + ::Ci::BuildTraceChunk.find_by_id(id).try do |chunk| chunk.persist_data! end end - # rubocop: enable CodeReuse/ActiveRecord end end diff --git a/app/workers/ci/pipeline_success_unlock_artifacts_worker.rb b/app/workers/ci/pipeline_success_unlock_artifacts_worker.rb index 160947fb38e..590514424bb 100644 --- a/app/workers/ci/pipeline_success_unlock_artifacts_worker.rb +++ b/app/workers/ci/pipeline_success_unlock_artifacts_worker.rb @@ -15,9 +15,12 @@ module Ci ::Ci::Pipeline.find_by_id(pipeline_id).try do |pipeline| break unless pipeline.has_archive_artifacts? - ::Ci::UnlockArtifactsService + results = ::Ci::UnlockArtifactsService .new(pipeline.project, pipeline.user) .execute(pipeline.ci_ref, pipeline) + + log_extra_metadata_on_done(:unlocked_pipelines, results[:unlocked_pipelines]) + log_extra_metadata_on_done(:unlocked_job_artifacts, results[:unlocked_job_artifacts]) end end end diff --git a/app/workers/ci/ref_delete_unlock_artifacts_worker.rb b/app/workers/ci/ref_delete_unlock_artifacts_worker.rb index 0c217644cc4..aeadf111bfb 100644 --- a/app/workers/ci/ref_delete_unlock_artifacts_worker.rb +++ b/app/workers/ci/ref_delete_unlock_artifacts_worker.rb @@ -15,9 +15,12 @@ module Ci ::Project.find_by_id(project_id).try do |project| ::User.find_by_id(user_id).try do |user| project.ci_refs.find_by_ref_path(ref_path).try do |ci_ref| - ::Ci::UnlockArtifactsService + results = ::Ci::UnlockArtifactsService .new(project, user) .execute(ci_ref) + + log_extra_metadata_on_done(:unlocked_pipelines, results[:unlocked_pipelines]) + log_extra_metadata_on_done(:unlocked_job_artifacts, results[:unlocked_job_artifacts]) end end end diff --git a/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb b/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb index 98b4f4ad73a..533cb7c425f 100644 --- a/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb +++ b/app/workers/ci/resource_groups/assign_resource_from_resource_group_worker.rb @@ -21,7 +21,7 @@ module Ci # Therefore, we can deduplicate the sidekiq jobs until the on-going # assignment process has been finished. idempotent! - deduplicate :until_executed + deduplicate :until_executed, if_deduplicated: :reschedule_once def perform(resource_group_id) ::Ci::ResourceGroup.find_by_id(resource_group_id).try do |resource_group| diff --git a/app/workers/cluster_update_app_worker.rb b/app/workers/cluster_update_app_worker.rb index cd2b2e38ea4..97fdec02ba4 100644 --- a/app/workers/cluster_update_app_worker.rb +++ b/app/workers/cluster_update_app_worker.rb @@ -26,16 +26,14 @@ class ClusterUpdateAppWorker # rubocop:disable Scalability/IdempotentWorker private - # rubocop: disable CodeReuse/ActiveRecord def execute(app_name, app_id, project_id, scheduled_time) - project = Project.find_by(id: project_id) + project = Project.find_by_id(project_id) return unless project find_application(app_name, app_id) do |app| update_prometheus(app, scheduled_time, project) end end - # rubocop: enable CodeReuse/ActiveRecord def update_prometheus(app, scheduled_time, project) return unless app.managed_prometheus? diff --git a/app/workers/clusters/applications/check_prometheus_health_worker.rb b/app/workers/clusters/integrations/check_prometheus_health_worker.rb index 4f85c5c5b7a..0c0d86e975c 100644 --- a/app/workers/clusters/applications/check_prometheus_health_worker.rb +++ b/app/workers/clusters/integrations/check_prometheus_health_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Clusters - module Applications + module Integrations class CheckPrometheusHealthWorker include ApplicationWorker @@ -12,7 +12,6 @@ module Clusters include CronjobQueue # rubocop:enable Scalability/CronWorkerContext - queue_namespace :incident_management feature_category :incident_management urgency :low @@ -22,11 +21,11 @@ module Clusters def perform demo_project_ids = Gitlab::Monitor::DemoProjects.primary_keys - clusters = Clusters::Cluster.with_application_prometheus + clusters = Clusters::Cluster.with_integration_prometheus .with_project_http_integrations(demo_project_ids) # Move to a seperate worker with scoped context if expanded to do work on customer projects - clusters.each { |cluster| Clusters::Applications::PrometheusHealthCheckService.new(cluster).execute } + clusters.each { |cluster| Clusters::Integrations::PrometheusHealthCheckService.new(cluster).execute } end end end diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb index 3399a4f9b57..03a0b5fae00 100644 --- a/app/workers/concerns/application_worker.rb +++ b/app/workers/concerns/application_worker.rb @@ -14,6 +14,7 @@ module ApplicationWorker LOGGING_EXTRA_KEY = 'extra' DEFAULT_DELAY_INTERVAL = 1 + SAFE_PUSH_BULK_LIMIT = 1000 included do set_queue @@ -54,6 +55,12 @@ module ApplicationWorker subclass.after_set_class_attribute { subclass.set_queue } end + def with_status + status_from_class = self.sidekiq_options_hash['status_expiration'] + + set(status_expiration: status_from_class || Gitlab::SidekiqStatus::DEFAULT_EXPIRATION) + end + def generated_queue_name Gitlab::SidekiqConfig::WorkerRouter.queue_name_from_worker_name(self) end @@ -130,29 +137,62 @@ module ApplicationWorker end end + def log_bulk_perform_async? + @log_bulk_perform_async + end + + def log_bulk_perform_async! + @log_bulk_perform_async = true + end + def queue_size Sidekiq::Queue.new(queue).size end def bulk_perform_async(args_list) - Sidekiq::Client.push_bulk('class' => self, 'args' => args_list) + if log_bulk_perform_async? + Sidekiq.logger.info('class' => self.name, 'args_list' => args_list, 'args_list_count' => args_list.length, 'message' => 'Inserting multiple jobs') + end + + do_push_bulk(args_list).tap do |job_ids| + if log_bulk_perform_async? + Sidekiq.logger.info('class' => self.name, 'jid_list' => job_ids, 'jid_list_count' => job_ids.length, 'message' => 'Completed JID insertion') + end + end end def bulk_perform_in(delay, args_list, batch_size: nil, batch_delay: nil) now = Time.now.to_i - schedule = now + delay.to_i + base_schedule_at = now + delay.to_i - if schedule <= now - raise ArgumentError, _('The schedule time must be in the future!') + if base_schedule_at <= now + raise ArgumentError, 'The schedule time must be in the future!' end + schedule_at = base_schedule_at + if batch_size && batch_delay - args_list.each_slice(batch_size.to_i).with_index do |args_batch, idx| - batch_schedule = schedule + idx * batch_delay.to_i - Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch, 'at' => batch_schedule) + batch_size = batch_size.to_i + batch_delay = batch_delay.to_i + + raise ArgumentError, 'batch_size should be greater than 0' unless batch_size > 0 + raise ArgumentError, 'batch_delay should be greater than 0' unless batch_delay > 0 + + # build an array of schedules corresponding to each item in `args_list` + bulk_schedule_at = Array.new(args_list.size) do |index| + batch_number = index / batch_size + base_schedule_at + (batch_number * batch_delay) + end + + schedule_at = bulk_schedule_at + end + + if Feature.enabled?(:sidekiq_push_bulk_in_batches) + in_safe_limit_batches(args_list, schedule_at) do |args_batch, schedule_at_for_batch| + Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch, 'at' => schedule_at_for_batch) end else - Sidekiq::Client.push_bulk('class' => self, 'args' => args_list, 'at' => schedule) + Sidekiq::Client.push_bulk('class' => self, 'args' => args_list, 'at' => schedule_at) end end @@ -161,5 +201,44 @@ module ApplicationWorker def delay_interval DEFAULT_DELAY_INTERVAL.seconds end + + private + + def do_push_bulk(args_list) + if Feature.enabled?(:sidekiq_push_bulk_in_batches) + in_safe_limit_batches(args_list) do |args_batch, _| + Sidekiq::Client.push_bulk('class' => self, 'args' => args_batch) + end + else + Sidekiq::Client.push_bulk('class' => self, 'args' => args_list) + end + end + + def in_safe_limit_batches(args_list, schedule_at = nil, safe_limit = SAFE_PUSH_BULK_LIMIT) + # `schedule_at` could be one of + # - nil. + # - a single Numeric that represents time, like `30.minutes.from_now.to_i`. + # - an array, where each element is a Numeric that reprsents time. + # - Each element in this array would correspond to the time at which + # - the job in `args_list` at the corresponding index needs to be scheduled. + + # In the case where `schedule_at` is an array of Numeric, it needs to be sliced + # in the same manner as the `args_list`, with each slice containing `safe_limit` + # number of elements. + schedule_at = schedule_at.each_slice(safe_limit).to_a if schedule_at.is_a?(Array) + + args_list.each_slice(safe_limit).with_index.flat_map do |args_batch, index| + schedule_at_for_batch = process_schedule_at_for_batch(schedule_at, index) + + yield(args_batch, schedule_at_for_batch) + end + end + + def process_schedule_at_for_batch(schedule_at, index) + return unless schedule_at + return schedule_at[index] if schedule_at.is_a?(Array) && schedule_at.all?(Array) + + schedule_at + end end end diff --git a/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb b/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb index eb1af0869bd..0a43a0fc4d2 100644 --- a/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb +++ b/app/workers/concerns/gitlab/github_import/rescheduling_methods.rb @@ -8,9 +8,8 @@ module Gitlab # project_id - The ID of the GitLab project to import the note into. # hash - A Hash containing the details of the GitHub object to import. # notify_key - The Redis key to notify upon completion, if any. - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, hash, notify_key = nil) - project = Project.find_by(id: project_id) + project = Project.find_by_id(project_id) return notify_waiter(notify_key) unless project @@ -25,7 +24,6 @@ module Gitlab .perform_in(client.rate_limit_resets_in, project.id, hash, notify_key) end end - # rubocop: enable CodeReuse/ActiveRecord def try_import(*args) import(*args) diff --git a/app/workers/concerns/gitlab/github_import/stage_methods.rb b/app/workers/concerns/gitlab/github_import/stage_methods.rb index d7b4578af63..225716f6bf3 100644 --- a/app/workers/concerns/gitlab/github_import/stage_methods.rb +++ b/app/workers/concerns/gitlab/github_import/stage_methods.rb @@ -33,13 +33,13 @@ module Gitlab self.class.perform_in(client.rate_limit_resets_in, project.id) end - # rubocop: disable CodeReuse/ActiveRecord def find_project(id) # If the project has been marked as failed we want to bail out # automatically. - Project.joins_import_state.where(import_state: { status: :started }).find_by(id: id) + # rubocop: disable CodeReuse/ActiveRecord + Project.joins_import_state.where(import_state: { status: :started }).find_by_id(id) + # rubocop: enable CodeReuse/ActiveRecord end - # rubocop: enable CodeReuse/ActiveRecord def abort_on_failure false diff --git a/app/workers/concerns/gitlab/jira_import/import_worker.rb b/app/workers/concerns/gitlab/jira_import/import_worker.rb index 107b6e2e9be..d18b9ff023b 100644 --- a/app/workers/concerns/gitlab/jira_import/import_worker.rb +++ b/app/workers/concerns/gitlab/jira_import/import_worker.rb @@ -14,7 +14,7 @@ module Gitlab end def perform(project_id) - project = Project.find_by(id: project_id) # rubocop: disable CodeReuse/ActiveRecord + project = Project.find_by_id(project_id) return unless can_import?(project) diff --git a/app/workers/concerns/limited_capacity/worker.rb b/app/workers/concerns/limited_capacity/worker.rb index b4cdfda680f..bcedb4efcc0 100644 --- a/app/workers/concerns/limited_capacity/worker.rb +++ b/app/workers/concerns/limited_capacity/worker.rb @@ -47,7 +47,7 @@ module LimitedCapacity # would be occupied by a job that will be performed in the distant future. # We let the cron worker enqueue new jobs, this could be seen as our retry and # back off mechanism because the job might fail again if executed immediately. - sidekiq_options retry: 0 + sidekiq_options retry: 0, status_expiration: Gitlab::SidekiqStatus::DEFAULT_EXPIRATION deduplicate :none end diff --git a/app/workers/concerns/new_issuable.rb b/app/workers/concerns/new_issuable.rb index 482a74f49f7..d761f023cad 100644 --- a/app/workers/concerns/new_issuable.rb +++ b/app/workers/concerns/new_issuable.rb @@ -10,21 +10,17 @@ module NewIssuable user && issuable end - # rubocop: disable CodeReuse/ActiveRecord def set_user(user_id) - @user = User.find_by(id: user_id) # rubocop:disable Gitlab/ModuleWithInstanceVariables + @user = User.find_by_id(user_id) # rubocop:disable Gitlab/ModuleWithInstanceVariables log_error(User, user_id) unless @user # rubocop:disable Gitlab/ModuleWithInstanceVariables end - # rubocop: enable CodeReuse/ActiveRecord - # rubocop: disable CodeReuse/ActiveRecord def set_issuable(issuable_id) - @issuable = issuable_class.find_by(id: issuable_id) # rubocop:disable Gitlab/ModuleWithInstanceVariables + @issuable = issuable_class.find_by_id(issuable_id) # rubocop:disable Gitlab/ModuleWithInstanceVariables log_error(issuable_class, issuable_id) unless @issuable # rubocop:disable Gitlab/ModuleWithInstanceVariables end - # rubocop: enable CodeReuse/ActiveRecord def log_error(record_class, record_id) Gitlab::AppLogger.error("#{self.class}: couldn't find #{record_class} with ID=#{record_id}, skipping job") diff --git a/app/workers/concerns/todos_destroyer_queue.rb b/app/workers/concerns/todos_destroyer_queue.rb index 1bbccbfb1f9..1c31b64ad97 100644 --- a/app/workers/concerns/todos_destroyer_queue.rb +++ b/app/workers/concerns/todos_destroyer_queue.rb @@ -8,6 +8,6 @@ module TodosDestroyerQueue included do queue_namespace :todos_destroyer - feature_category :issue_tracking + feature_category :team_planning 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 69f5906f54c..7f7a77d0524 100644 --- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb +++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb @@ -159,7 +159,10 @@ module ContainerExpirationPolicies return unless tags_count && cached_tags_count && tags_count != 0 - log_extra_metadata_on_done(:cleanup_tags_service_cache_hit_ratio, cached_tags_count / tags_count.to_f) + ratio = cached_tags_count / tags_count.to_f + ratio_as_percentage = (ratio * 100).round(2) + + log_extra_metadata_on_done(:cleanup_tags_service_cache_hit_ratio, ratio_as_percentage) end def log_truncate(result) diff --git a/app/workers/create_commit_signature_worker.rb b/app/workers/create_commit_signature_worker.rb index 01a2e109967..c35d2d3b33b 100644 --- a/app/workers/create_commit_signature_worker.rb +++ b/app/workers/create_commit_signature_worker.rb @@ -12,7 +12,6 @@ class CreateCommitSignatureWorker idempotent! loggable_arguments 0 - # rubocop: disable CodeReuse/ActiveRecord def perform(commit_shas, project_id) # Older versions of Git::BranchPushService may push a single commit ID on # the stack. We need this to be backwards compatible. @@ -20,7 +19,7 @@ class CreateCommitSignatureWorker return if commit_shas.empty? - project = Project.find_by(id: project_id) + project = Project.find_by_id(project_id) return unless project commits = project.commits_by(oids: commit_shas) @@ -44,5 +43,4 @@ class CreateCommitSignatureWorker Gitlab::AppLogger.error("Failed to create signature for commit #{commit.id}. Error: #{e.message}") end end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/database/drop_detached_partitions_worker.rb b/app/workers/database/drop_detached_partitions_worker.rb index 1e4dc20a0d2..126c46a338b 100644 --- a/app/workers/database/drop_detached_partitions_worker.rb +++ b/app/workers/database/drop_detached_partitions_worker.rb @@ -12,7 +12,7 @@ module Database def perform Gitlab::Database::Partitioning.drop_detached_partitions ensure - Gitlab::Database::Partitioning::PartitionMonitoring.new.report_metrics + Gitlab::Database::Partitioning.report_metrics end end end diff --git a/app/workers/database/partition_management_worker.rb b/app/workers/database/partition_management_worker.rb index 5a1f139dc29..ba1ad7a0e81 100644 --- a/app/workers/database/partition_management_worker.rb +++ b/app/workers/database/partition_management_worker.rb @@ -14,7 +14,7 @@ module Database def perform Gitlab::Database::Partitioning.sync_partitions ensure - Gitlab::Database::Partitioning::PartitionMonitoring.new.report_metrics + Gitlab::Database::Partitioning.report_metrics end end end diff --git a/app/workers/delete_container_repository_worker.rb b/app/workers/delete_container_repository_worker.rb index beeca559060..a4d6adc2195 100644 --- a/app/workers/delete_container_repository_worker.rb +++ b/app/workers/delete_container_repository_worker.rb @@ -15,10 +15,9 @@ class DeleteContainerRepositoryWorker # rubocop:disable Scalability/IdempotentWo attr_reader :container_repository - # rubocop: disable CodeReuse/ActiveRecord def perform(current_user_id, container_repository_id) - current_user = User.find_by(id: current_user_id) - @container_repository = ContainerRepository.find_by(id: container_repository_id) + current_user = User.find_by_id(current_user_id) + @container_repository = ContainerRepository.find_by_id(container_repository_id) project = container_repository&.project return unless current_user && container_repository && project @@ -29,7 +28,6 @@ class DeleteContainerRepositoryWorker # rubocop:disable Scalability/IdempotentWo Projects::ContainerRepository::DestroyService.new(project, current_user).execute(container_repository) end end - # rubocop: enable CodeReuse/ActiveRecord # For ExclusiveLeaseGuard concern def lease_key diff --git a/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb b/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb index fed469e6dc8..6a1de00ce80 100644 --- a/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb +++ b/app/workers/dependency_proxy/image_ttl_group_policy_worker.rb @@ -13,9 +13,8 @@ module DependencyProxy def perform DependencyProxy::ImageTtlGroupPolicy.enabled.each do |policy| - # Technical Debt: change to read_before https://gitlab.com/gitlab-org/gitlab/-/issues/341536 - qualified_blobs = policy.group.dependency_proxy_blobs.active.updated_before(policy.ttl) - qualified_manifests = policy.group.dependency_proxy_manifests.active.updated_before(policy.ttl) + qualified_blobs = policy.group.dependency_proxy_blobs.active.read_before(policy.ttl) + qualified_manifests = policy.group.dependency_proxy_manifests.active.read_before(policy.ttl) enqueue_blob_cleanup_job if expire_artifacts(qualified_blobs, DependencyProxy::Blob) enqueue_manifest_cleanup_job if expire_artifacts(qualified_manifests, DependencyProxy::Manifest) diff --git a/app/workers/deployments/archive_in_project_worker.rb b/app/workers/deployments/archive_in_project_worker.rb new file mode 100644 index 00000000000..2de4cacbbd6 --- /dev/null +++ b/app/workers/deployments/archive_in_project_worker.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Deployments + class ArchiveInProjectWorker + include ApplicationWorker + + queue_namespace :deployment + feature_category :continuous_delivery + idempotent! + deduplicate :until_executed, including_scheduled: true + data_consistency :delayed + + def perform(project_id) + Project.find_by_id(project_id).try do |project| + Deployments::ArchiveInProjectService.new(project, nil).execute + end + end + end +end diff --git a/app/workers/detect_repository_languages_worker.rb b/app/workers/detect_repository_languages_worker.rb index 8c7ef6c9e32..702b83a3185 100644 --- a/app/workers/detect_repository_languages_worker.rb +++ b/app/workers/detect_repository_languages_worker.rb @@ -14,16 +14,14 @@ class DetectRepositoryLanguagesWorker # rubocop:disable Scalability/IdempotentWo attr_reader :project - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, user_id = nil) - @project = Project.find_by(id: project_id) + @project = Project.find_by_id(project_id) return unless project try_obtain_lease do ::Projects::DetectRepositoryLanguagesService.new(project).execute end end - # rubocop: enable CodeReuse/ActiveRecord private diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb index 51211834e06..321d492f0f3 100644 --- a/app/workers/email_receiver_worker.rb +++ b/app/workers/email_receiver_worker.rb @@ -7,7 +7,7 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :issue_tracking + feature_category :team_planning urgency :high weight 2 @@ -118,7 +118,9 @@ class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker end if reason - EmailRejectionMailer.rejection(reason, raw, can_retry).deliver_later + receiver.mail.body = nil + + EmailRejectionMailer.rejection(reason, receiver.mail.encoded, can_retry).deliver_later end end end diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index 0230a226567..d7bd8207f06 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -87,13 +87,14 @@ class EmailsOnPushWorker # rubocop:disable Scalability/IdempotentWorker private def send_email(recipient, project_id, options) - # Generating the body of this email can be expensive, so only do it once - @skip_premailer ||= email.present? - @email ||= Notify.repository_push_email(project_id, options) - - email.to = recipient - email.add_message_id - email.header[:skip_premailer] = true if skip_premailer - email.deliver_now + @email ||= Notify.repository_push_email(project_id, options).tap do |mail| + Premailer::Rails::Hook.perform(mail) + end + + current_email = email.dup + current_email.to = recipient + current_email.add_message_id + current_email.header[:skip_premailer] = true + current_email.deliver_now end end diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index 77b8f59e365..948e1a59b07 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -9,17 +9,17 @@ class ExpireBuildInstanceArtifactsWorker # rubocop:disable Scalability/Idempoten feature_category :build_artifacts - # rubocop: disable CodeReuse/ActiveRecord def perform(build_id) + # rubocop: disable CodeReuse/ActiveRecord build = Ci::Build .with_expired_artifacts .reorder(nil) - .find_by(id: build_id) + .find_by_id(build_id) + # rubocop: enable CodeReuse/ActiveRecord return unless build&.project && !build.project.pending_delete Gitlab::AppLogger.info("Removing artifacts for build #{build.id}...") build.erase_erasable_artifacts! end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/expire_job_cache_worker.rb b/app/workers/expire_job_cache_worker.rb index 7374f650546..3c5a7717d70 100644 --- a/app/workers/expire_job_cache_worker.rb +++ b/app/workers/expire_job_cache_worker.rb @@ -14,9 +14,8 @@ class ExpireJobCacheWorker # rubocop:disable Scalability/IdempotentWorker deduplicate :until_executing, including_scheduled: true idempotent! - # rubocop: disable CodeReuse/ActiveRecord def perform(job_id) - job = CommitStatus.preload(:pipeline, :project).find_by(id: job_id) + job = CommitStatus.preload(:pipeline, :project).find_by_id(job_id) # rubocop: disable CodeReuse/ActiveRecord return unless job pipeline = job.pipeline @@ -25,7 +24,6 @@ class ExpireJobCacheWorker # rubocop:disable Scalability/IdempotentWorker Gitlab::EtagCaching::Store.new.touch(project_job_path(project, job)) ExpirePipelineCacheWorker.perform_async(pipeline.id) end - # rubocop: enable CodeReuse/ActiveRecord private diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb index 07e6939d1c7..9a0c617da57 100644 --- a/app/workers/expire_pipeline_cache_worker.rb +++ b/app/workers/expire_pipeline_cache_worker.rb @@ -17,13 +17,11 @@ class ExpirePipelineCacheWorker # Uncomment once https://gitlab.com/gitlab-org/gitlab/-/issues/325291 is resolved # idempotent! - # rubocop: disable CodeReuse/ActiveRecord def perform(pipeline_id) - pipeline = Ci::Pipeline.find_by(id: pipeline_id) + pipeline = Ci::Pipeline.find_by_id(pipeline_id) return unless pipeline Ci::ExpirePipelineCacheService.new.execute(pipeline) end - # rubocop: enable CodeReuse/ActiveRecord end # rubocop:enable Scalability/IdempotentWorker diff --git a/app/workers/export_csv_worker.rb b/app/workers/export_csv_worker.rb index 68feaa61cdd..c5feb02b2bd 100644 --- a/app/workers/export_csv_worker.rb +++ b/app/workers/export_csv_worker.rb @@ -7,7 +7,7 @@ class ExportCsvWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :issue_tracking + feature_category :team_planning worker_resource_boundary :cpu loggable_arguments 2 diff --git a/app/workers/gitlab/jira_import/import_issue_worker.rb b/app/workers/gitlab/jira_import/import_issue_worker.rb index eabe7328b92..3824cc1f3ef 100644 --- a/app/workers/gitlab/jira_import/import_issue_worker.rb +++ b/app/workers/gitlab/jira_import/import_issue_worker.rb @@ -54,7 +54,7 @@ module Gitlab label_link_attrs << build_label_attrs(issue_id, import_label_id.to_i) - Gitlab::Database.main.bulk_insert(LabelLink.table_name, label_link_attrs) # rubocop:disable Gitlab/BulkInsert + ApplicationRecord.legacy_bulk_insert(LabelLink.table_name, label_link_attrs) # rubocop:disable Gitlab/BulkInsert end def assign_issue(project_id, issue_id, assignee_ids) @@ -62,7 +62,7 @@ module Gitlab assignee_attrs = assignee_ids.map { |user_id| { issue_id: issue_id, user_id: user_id } } - Gitlab::Database.main.bulk_insert(IssueAssignee.table_name, assignee_attrs) # rubocop:disable Gitlab/BulkInsert + ApplicationRecord.legacy_bulk_insert(IssueAssignee.table_name, assignee_attrs) # rubocop:disable Gitlab/BulkInsert end def build_label_attrs(issue_id, label_id) diff --git a/app/workers/gitlab/jira_import/stage/start_import_worker.rb b/app/workers/gitlab/jira_import/stage/start_import_worker.rb index e0de3ee169e..3f6ad66e278 100644 --- a/app/workers/gitlab/jira_import/stage/start_import_worker.rb +++ b/app/workers/gitlab/jira_import/stage/start_import_worker.rb @@ -16,7 +16,7 @@ module Gitlab attr_reader :project def perform(project_id) - @project = Project.find_by(id: project_id) # rubocop: disable CodeReuse/ActiveRecord + @project = Project.find_by_id(project_id) return unless start_import diff --git a/app/workers/hashed_storage/project_migrate_worker.rb b/app/workers/hashed_storage/project_migrate_worker.rb index bcc80cc2a70..460aac3f2f2 100644 --- a/app/workers/hashed_storage/project_migrate_worker.rb +++ b/app/workers/hashed_storage/project_migrate_worker.rb @@ -16,12 +16,11 @@ module HashedStorage attr_reader :project_id - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, old_disk_path = nil) @project_id = project_id # we need to set this in order to create the lease_key try_obtain_lease do - project = Project.without_deleted.find_by(id: project_id) + project = Project.without_deleted.find_by_id(project_id) break unless project && project.storage_upgradable? old_disk_path ||= Storage::LegacyProject.new(project).disk_path @@ -29,6 +28,5 @@ module HashedStorage ::Projects::HashedStorage::MigrationService.new(project, old_disk_path, logger: logger).execute end end - # rubocop: enable CodeReuse/ActiveRecord end end diff --git a/app/workers/hashed_storage/project_rollback_worker.rb b/app/workers/hashed_storage/project_rollback_worker.rb index 07a7ab63718..91ea3dd9189 100644 --- a/app/workers/hashed_storage/project_rollback_worker.rb +++ b/app/workers/hashed_storage/project_rollback_worker.rb @@ -16,12 +16,11 @@ module HashedStorage attr_reader :project_id - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, old_disk_path = nil) @project_id = project_id # we need to set this in order to create the lease_key try_obtain_lease do - project = Project.without_deleted.find_by(id: project_id) + project = Project.without_deleted.find_by_id(project_id) break unless project old_disk_path ||= project.disk_path @@ -29,6 +28,5 @@ module HashedStorage ::Projects::HashedStorage::RollbackService.new(project, old_disk_path, logger: logger).execute end end - # rubocop: enable CodeReuse/ActiveRecord end end diff --git a/app/workers/import_issues_csv_worker.rb b/app/workers/import_issues_csv_worker.rb index 58e411c7b19..fe5b1c13d56 100644 --- a/app/workers/import_issues_csv_worker.rb +++ b/app/workers/import_issues_csv_worker.rb @@ -8,7 +8,7 @@ class ImportIssuesCsvWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 idempotent! - feature_category :issue_tracking + feature_category :team_planning worker_resource_boundary :cpu weight 2 diff --git a/app/workers/integrations/create_external_cross_reference_worker.rb b/app/workers/integrations/create_external_cross_reference_worker.rb new file mode 100644 index 00000000000..02c1315249e --- /dev/null +++ b/app/workers/integrations/create_external_cross_reference_worker.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +module Integrations + class CreateExternalCrossReferenceWorker + include ApplicationWorker + + data_consistency :delayed + + feature_category :integrations + urgency :low + idempotent! + deduplicate :until_executed, including_scheduled: true + loggable_arguments 2 + + def perform(project_id, external_issue_id, mentionable_type, mentionable_id, author_id) + project = Project.find_by_id(project_id) || return + author = User.find_by_id(author_id) || return + mentionable = find_mentionable(mentionable_type, mentionable_id, project) || return + external_issue = ExternalIssue.new(external_issue_id, project) + + project.external_issue_tracker.create_cross_reference_note( + external_issue, + mentionable, + author + ) + end + + private + + def find_mentionable(mentionable_type, mentionable_id, project) + mentionable_class = mentionable_type.safe_constantize + + # Passing an invalid mentionable_class is a developer error, so we don't want to retry the job + # but still track the exception on production, and raise it in development. + unless mentionable_class && mentionable_class < Mentionable + Gitlab::ErrorTracking.track_and_raise_for_dev_exception(ArgumentError.new("Unexpected class '#{mentionable_type}' is not a Mentionable")) + return + end + + if mentionable_type == 'Commit' + project.commit(mentionable_id) + else + mentionable_class.find_by_id(mentionable_id) + end + end + end +end diff --git a/app/workers/invalid_gpg_signature_update_worker.rb b/app/workers/invalid_gpg_signature_update_worker.rb index c9567e102d3..7dc1e395597 100644 --- a/app/workers/invalid_gpg_signature_update_worker.rb +++ b/app/workers/invalid_gpg_signature_update_worker.rb @@ -10,13 +10,11 @@ class InvalidGpgSignatureUpdateWorker # rubocop:disable Scalability/IdempotentWo feature_category :source_code_management weight 2 - # rubocop: disable CodeReuse/ActiveRecord def perform(gpg_key_id) - gpg_key = GpgKey.find_by(id: gpg_key_id) + gpg_key = GpgKey.find_by_id(gpg_key_id) return unless gpg_key Gitlab::Gpg::InvalidGpgSignatureUpdater.new(gpg_key).run end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/issuable/label_links_destroy_worker.rb b/app/workers/issuable/label_links_destroy_worker.rb index f88c061bafb..da785550a43 100644 --- a/app/workers/issuable/label_links_destroy_worker.rb +++ b/app/workers/issuable/label_links_destroy_worker.rb @@ -7,7 +7,7 @@ module Issuable data_consistency :always idempotent! - feature_category :issue_tracking + feature_category :team_planning def perform(target_id, target_type) ::Issuable::DestroyLabelLinksService.new(target_id, target_type).execute diff --git a/app/workers/issuable_export_csv_worker.rb b/app/workers/issuable_export_csv_worker.rb index 7e2c3407772..9d543a21dc3 100644 --- a/app/workers/issuable_export_csv_worker.rb +++ b/app/workers/issuable_export_csv_worker.rb @@ -7,7 +7,7 @@ class IssuableExportCsvWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :issue_tracking + feature_category :team_planning worker_resource_boundary :cpu loggable_arguments 2 diff --git a/app/workers/issuables/clear_groups_issue_counter_worker.rb b/app/workers/issuables/clear_groups_issue_counter_worker.rb index 9e62224b83d..82026bc21c7 100644 --- a/app/workers/issuables/clear_groups_issue_counter_worker.rb +++ b/app/workers/issuables/clear_groups_issue_counter_worker.rb @@ -8,7 +8,7 @@ module Issuables idempotent! urgency :low - feature_category :issue_tracking + feature_category :team_planning def perform(group_ids = []) return if group_ids.empty? diff --git a/app/workers/issue_due_scheduler_worker.rb b/app/workers/issue_due_scheduler_worker.rb index ad3470ae64b..ab586dce717 100644 --- a/app/workers/issue_due_scheduler_worker.rb +++ b/app/workers/issue_due_scheduler_worker.rb @@ -7,7 +7,7 @@ class IssueDueSchedulerWorker # rubocop:disable Scalability/IdempotentWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext - feature_category :issue_tracking + feature_category :team_planning # rubocop: disable CodeReuse/ActiveRecord def perform diff --git a/app/workers/issue_placement_worker.rb b/app/workers/issue_placement_worker.rb index 22e2a8e95f4..cfd72b90a42 100644 --- a/app/workers/issue_placement_worker.rb +++ b/app/workers/issue_placement_worker.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +# todo: remove this worker and it's queue definition from all_queues after Issues::PlacementWorker is deployed +# We want to keep it for one release in case some jobs are already scheduled in the old queue so we need the worker +# to be available to finish those. All new jobs will be queued into the new queue. class IssuePlacementWorker include ApplicationWorker @@ -9,7 +12,7 @@ class IssuePlacementWorker idempotent! deduplicate :until_executed, including_scheduled: true - feature_category :issue_tracking + feature_category :team_planning urgency :high worker_resource_boundary :cpu weight 2 diff --git a/app/workers/issue_rebalancing_worker.rb b/app/workers/issue_rebalancing_worker.rb index 01984197aae..a43e76feae4 100644 --- a/app/workers/issue_rebalancing_worker.rb +++ b/app/workers/issue_rebalancing_worker.rb @@ -1,5 +1,8 @@ # frozen_string_literal: true +# todo: remove this worker and it's queue definition from all_queues after Issue::RebalancingWorker is released. +# We want to keep it for one release in case some jobs are already scheduled in the old queue so we need the worker +# to be available to finish those. All new jobs will be queued into the new queue. class IssueRebalancingWorker include ApplicationWorker @@ -9,13 +12,14 @@ class IssueRebalancingWorker idempotent! urgency :low - feature_category :issue_tracking + feature_category :team_planning deduplicate :until_executed, including_scheduled: true def perform(ignore = nil, project_id = nil, root_namespace_id = nil) # we need to have exactly one of the project_id and root_namespace_id params be non-nil raise ArgumentError, "Expected only one of the params project_id: #{project_id} and root_namespace_id: #{root_namespace_id}" if project_id && root_namespace_id return if project_id.nil? && root_namespace_id.nil? + return if ::Gitlab::Issues::Rebalancing::State.rebalance_recently_finished?(project_id, root_namespace_id) # pull the projects collection to be rebalanced either the project if namespace is not a group(i.e. user namesapce) # or the root namespace, this also makes the worker backward compatible with previous version where a project_id was diff --git a/app/workers/issues/placement_worker.rb b/app/workers/issues/placement_worker.rb new file mode 100644 index 00000000000..ec29a754128 --- /dev/null +++ b/app/workers/issues/placement_worker.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +module Issues + class PlacementWorker + include ApplicationWorker + + data_consistency :always + + sidekiq_options retry: 3 + + idempotent! + deduplicate :until_executed, including_scheduled: true + feature_category :team_planning + urgency :high + worker_resource_boundary :cpu + weight 2 + + # Move at most the most recent 100 issues + QUERY_LIMIT = 100 + + # rubocop: disable CodeReuse/ActiveRecord + def perform(issue_id, project_id = nil) + issue = find_issue(issue_id, project_id) + return unless issue + + # Temporary disable moving null elements because of performance problems + # For more information check https://gitlab.com/gitlab-com/gl-infra/production/-/issues/4321 + return if issue.blocked_for_repositioning? + + # Move the oldest 100 unpositioned items to the end. + # This is to deal with out-of-order execution of the worker, + # while preserving creation order. + to_place = Issue + .relative_positioning_query_base(issue) + .with_null_relative_position + .order({ created_at: :asc }, { id: :asc }) + .limit(QUERY_LIMIT + 1) + .to_a + + 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::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) + Issues::RebalancingWorker.perform_async(nil, *root_namespace_id_to_rebalance(issue, project_id)) + end + + def find_issue(issue_id, project_id) + return Issue.id_in(issue_id).take if issue_id + + project = Project.id_in(project_id).take + return unless project + + project.issues.take + end + # rubocop: enable CodeReuse/ActiveRecord + + private + + def root_namespace_id_to_rebalance(issue, project_id) + project_id = project_id.presence || issue.project_id + Project.find(project_id)&.self_or_root_group_ids + end + end +end diff --git a/app/workers/issues/rebalancing_worker.rb b/app/workers/issues/rebalancing_worker.rb new file mode 100644 index 00000000000..466617d9fa1 --- /dev/null +++ b/app/workers/issues/rebalancing_worker.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Issues + class RebalancingWorker + include ApplicationWorker + + data_consistency :always + + sidekiq_options retry: 3 + + idempotent! + urgency :low + feature_category :team_planning + deduplicate :until_executed, including_scheduled: true + + def perform(ignore = nil, project_id = nil, root_namespace_id = nil) + # we need to have exactly one of the project_id and root_namespace_id params be non-nil + raise ArgumentError, "Expected only one of the params project_id: #{project_id} and root_namespace_id: #{root_namespace_id}" if project_id && root_namespace_id + return if project_id.nil? && root_namespace_id.nil? + + # pull the projects collection to be rebalanced either the project if namespace is not a group(i.e. user namesapce) + # or the root namespace, this also makes the worker backward compatible with previous version where a project_id was + # passed as the param + projects_to_rebalance = projects_collection(project_id, root_namespace_id) + + # something might have happened with the namespace between scheduling the worker and actually running it, + # maybe it was removed. + if projects_to_rebalance.blank? + Gitlab::ErrorTracking.log_exception( + ArgumentError.new("Projects to be rebalanced not found for arguments: project_id #{project_id}, root_namespace_id: #{root_namespace_id}"), + { project_id: project_id, root_namespace_id: root_namespace_id }) + + return + end + + Issues::RelativePositionRebalancingService.new(projects_to_rebalance).execute + rescue Issues::RelativePositionRebalancingService::TooManyConcurrentRebalances => e + Gitlab::ErrorTracking.log_exception(e, root_namespace_id: root_namespace_id, project_id: project_id) + end + + private + + def projects_collection(project_id, root_namespace_id) + # we can have either project_id(older version) or project_id if project is part of a user namespace and not a group + # or root_namespace_id(newer version) never both. + return Project.id_in([project_id]) if project_id + + Namespace.find_by_id(root_namespace_id)&.all_projects + end + end +end diff --git a/app/workers/issues/reschedule_stuck_issue_rebalances_worker.rb b/app/workers/issues/reschedule_stuck_issue_rebalances_worker.rb new file mode 100644 index 00000000000..d1759589cc0 --- /dev/null +++ b/app/workers/issues/reschedule_stuck_issue_rebalances_worker.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +module Issues + class RescheduleStuckIssueRebalancesWorker + include ApplicationWorker + include CronjobQueue + + data_consistency :sticky + + idempotent! + urgency :low + feature_category :team_planning + deduplicate :until_executed, including_scheduled: true + + def perform + namespace_ids, project_ids = ::Gitlab::Issues::Rebalancing::State.fetch_rebalancing_groups_and_projects + + return if namespace_ids.blank? && project_ids.blank? + + namespaces = Namespace.id_in(namespace_ids) + projects = Project.id_in(project_ids) + + IssueRebalancingWorker.bulk_perform_async_with_contexts( + namespaces, + arguments_proc: -> (namespace) { [nil, nil, namespace.id] }, + context_proc: -> (namespace) { { namespace: namespace } } + ) + + IssueRebalancingWorker.bulk_perform_async_with_contexts( + projects, + arguments_proc: -> (project) { [nil, project.id, nil] }, + context_proc: -> (project) { { project: project } } + ) + end + end +end diff --git a/app/workers/loose_foreign_keys/cleanup_worker.rb b/app/workers/loose_foreign_keys/cleanup_worker.rb new file mode 100644 index 00000000000..b4565dbf624 --- /dev/null +++ b/app/workers/loose_foreign_keys/cleanup_worker.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module LooseForeignKeys + class CleanupWorker + include ApplicationWorker + include Gitlab::ExclusiveLeaseHelpers + include CronjobQueue # rubocop: disable Scalability/CronWorkerContext + + feature_category :sharding + data_consistency :always + idempotent! + + def perform + return if Feature.disabled?(:loose_foreign_key_cleanup, default_enabled: :yaml) + + ttl = ModificationTracker::MAX_RUNTIME + 1.minute + in_lock(self.class.name.underscore, ttl: ttl, retries: 0) do + # TODO: Iterate over the connections + # https://gitlab.com/gitlab-org/gitlab/-/issues/341513 + stats = ProcessDeletedRecordsService.new(connection: ApplicationRecord.connection).execute + log_extra_metadata_on_done(:stats, stats) + end + end + end +end diff --git a/app/workers/mail_scheduler/issue_due_worker.rb b/app/workers/mail_scheduler/issue_due_worker.rb index 4c17f8df722..585fa43916e 100644 --- a/app/workers/mail_scheduler/issue_due_worker.rb +++ b/app/workers/mail_scheduler/issue_due_worker.rb @@ -9,7 +9,7 @@ module MailScheduler sidekiq_options retry: 3 include MailSchedulerQueue - feature_category :issue_tracking + feature_category :team_planning # rubocop: disable CodeReuse/ActiveRecord def perform(project_id) diff --git a/app/workers/mail_scheduler/notification_service_worker.rb b/app/workers/mail_scheduler/notification_service_worker.rb index 0e6494a45d6..25c9ac5547b 100644 --- a/app/workers/mail_scheduler/notification_service_worker.rb +++ b/app/workers/mail_scheduler/notification_service_worker.rb @@ -11,7 +11,7 @@ module MailScheduler sidekiq_options retry: 3 include MailSchedulerQueue - feature_category :issue_tracking + feature_category :team_planning worker_resource_boundary :cpu loggable_arguments 0 diff --git a/app/workers/namespaces/invite_team_email_worker.rb b/app/workers/namespaces/invite_team_email_worker.rb new file mode 100644 index 00000000000..eabf33a7fba --- /dev/null +++ b/app/workers/namespaces/invite_team_email_worker.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Namespaces + class InviteTeamEmailWorker # rubocop:disable Scalability/IdempotentWorker + include ApplicationWorker + + data_consistency :always + + feature_category :experimentation_activation + urgency :low + + def perform(group_id, user_id) + # rubocop: disable CodeReuse/ActiveRecord + user = User.find_by(id: user_id) + group = Group.find_by(id: group_id) + # rubocop: enable CodeReuse/ActiveRecord + return unless user && group + + Namespaces::InviteTeamEmailService.send_email(user, group) + end + end +end diff --git a/app/workers/new_issue_worker.rb b/app/workers/new_issue_worker.rb index 899545fc02c..13936fac1e4 100644 --- a/app/workers/new_issue_worker.rb +++ b/app/workers/new_issue_worker.rb @@ -8,7 +8,7 @@ class NewIssueWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 include NewIssuable - feature_category :issue_tracking + feature_category :team_planning urgency :high worker_resource_boundary :cpu weight 2 diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb index e54d84e382e..ecc78236161 100644 --- a/app/workers/new_note_worker.rb +++ b/app/workers/new_note_worker.rb @@ -7,21 +7,19 @@ class NewNoteWorker # rubocop:disable Scalability/IdempotentWorker sidekiq_options retry: 3 - feature_category :issue_tracking + feature_category :team_planning urgency :high worker_resource_boundary :cpu weight 2 # Keep extra parameter to preserve backwards compatibility with # old `NewNoteWorker` jobs (can remove later) - # rubocop: disable CodeReuse/ActiveRecord def perform(note_id, _params = {}) - if note = Note.find_by(id: note_id) + if note = Note.find_by_id(note_id) NotificationService.new.new_note(note) unless note.skip_notification? Notes::PostProcessService.new(note).execute else Gitlab::AppLogger.error("NewNoteWorker: couldn't find note with ID=#{note_id}, skipping job") end end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/pages_domain_verification_worker.rb b/app/workers/pages_domain_verification_worker.rb index 59de00d40d5..1696abd7b70 100644 --- a/app/workers/pages_domain_verification_worker.rb +++ b/app/workers/pages_domain_verification_worker.rb @@ -9,15 +9,13 @@ class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWork feature_category :pages - # rubocop: disable CodeReuse/ActiveRecord def perform(domain_id) return if Gitlab::Database.read_only? - domain = PagesDomain.find_by(id: domain_id) + domain = PagesDomain.find_by_id(domain_id) return unless domain VerifyPagesDomainService.new(domain).execute end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb index 5e951ab2c3a..cceafbc7d2d 100644 --- a/app/workers/pages_worker.rb +++ b/app/workers/pages_worker.rb @@ -14,15 +14,13 @@ class PagesWorker # rubocop:disable Scalability/IdempotentWorker send(action, *arg) # rubocop:disable GitlabSecurity/PublicSend end - # rubocop: disable CodeReuse/ActiveRecord def deploy(build_id) - build = Ci::Build.find_by(id: build_id) + build = Ci::Build.find_by_id(build_id) update_contents = Projects::UpdatePagesService.new(build.project, build).execute if update_contents[:status] == :success Projects::UpdatePagesConfigurationService.new(build.project).execute end end - # rubocop: enable CodeReuse/ActiveRecord def remove(namespace_path, project_path) full_path = File.join(Settings.pages.path, namespace_path, project_path) diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index c67f3860a50..eb5d0086592 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -10,12 +10,10 @@ class PipelineHooksWorker # rubocop:disable Scalability/IdempotentWorker worker_resource_boundary :cpu data_consistency :delayed - # rubocop: disable CodeReuse/ActiveRecord def perform(pipeline_id) - pipeline = Ci::Pipeline.find_by(id: pipeline_id) + pipeline = Ci::Pipeline.find_by_id(pipeline_id) return unless pipeline Ci::Pipelines::HookService.new(pipeline).execute end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb index c2580c3d48b..4e98c7268ac 100644 --- a/app/workers/pipeline_metrics_worker.rb +++ b/app/workers/pipeline_metrics_worker.rb @@ -10,14 +10,12 @@ class PipelineMetricsWorker # rubocop:disable Scalability/IdempotentWorker urgency :high - # rubocop: disable CodeReuse/ActiveRecord def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| + Ci::Pipeline.find_by_id(pipeline_id).try do |pipeline| update_metrics_for_active_pipeline(pipeline) if pipeline.active? update_metrics_for_succeeded_pipeline(pipeline) if pipeline.success? end end - # rubocop: enable CodeReuse/ActiveRecord private @@ -29,11 +27,9 @@ class PipelineMetricsWorker # rubocop:disable Scalability/IdempotentWorker metrics(pipeline).update_all(latest_build_started_at: pipeline.started_at, latest_build_finished_at: pipeline.finished_at, pipeline_id: pipeline.id) end - # rubocop: disable CodeReuse/ActiveRecord def metrics(pipeline) - MergeRequest::Metrics.where(merge_request_id: merge_requests(pipeline)) + MergeRequest::Metrics.where(merge_request_id: merge_requests(pipeline)) # rubocop: disable CodeReuse/ActiveRecord end - # rubocop: enable CodeReuse/ActiveRecord def merge_requests(pipeline) pipeline.merge_requests_as_head_pipeline.map(&:id) diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 9370b361068..b4712aaeafb 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -16,13 +16,11 @@ class PipelineProcessWorker idempotent! deduplicate :until_executing - # rubocop: disable CodeReuse/ActiveRecord def perform(pipeline_id) - Ci::Pipeline.find_by(id: pipeline_id).try do |pipeline| + Ci::Pipeline.find_by_id(pipeline_id).try do |pipeline| Ci::ProcessPipelineService .new(pipeline) .execute end end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index 7d0322361b8..45af15216fc 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -128,7 +128,6 @@ class PostReceive end def after_project_changes_hooks(project, user, refs, changes) - experiment(:empty_repo_upload, project: project).track_initial_write repository_update_hook_data = Gitlab::DataBuilder::Repository.update(project, user, changes, refs) SystemHooksService.new.execute_hooks(repository_update_hook_data, :repository_update_hooks) Gitlab::UsageDataCounters::SourceCodeCounter.count(:pushes) diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb index 328fdc4717c..0e90b41e28d 100644 --- a/app/workers/project_cache_worker.rb +++ b/app/workers/project_cache_worker.rb @@ -23,9 +23,8 @@ class ProjectCacheWorker # refresh, if empty all columns will be refreshed # refresh_statistics - A boolean that determines whether project statistics should # be updated. - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, files = [], statistics = [], refresh_statistics = true) - project = Project.find_by(id: project_id) + project = Project.find_by_id(project_id) return unless project @@ -37,7 +36,6 @@ class ProjectCacheWorker project.cleanup end - # rubocop: enable CodeReuse/ActiveRecord # NOTE: triggering both an immediate update and one in 15 minutes if we # successfully obtain the lease. That way, we only need to wait for the diff --git a/app/workers/propagate_service_template_worker.rb b/app/workers/propagate_service_template_worker.rb index 6b8382ae433..908f867279f 100644 --- a/app/workers/propagate_service_template_worker.rb +++ b/app/workers/propagate_service_template_worker.rb @@ -13,13 +13,11 @@ class PropagateServiceTemplateWorker # rubocop:disable Scalability/IdempotentWor LEASE_TIMEOUT = 4.hours.to_i - # rubocop: disable CodeReuse/ActiveRecord def perform(template_id) return unless try_obtain_lease_for(template_id) - Admin::PropagateServiceTemplate.propagate(Integration.find_by(id: template_id)) + Admin::PropagateServiceTemplate.propagate(Integration.find_by_id(template_id)) end - # rubocop: enable CodeReuse/ActiveRecord private diff --git a/app/workers/run_pipeline_schedule_worker.rb b/app/workers/run_pipeline_schedule_worker.rb index 12042ebc4f0..f08d8231e43 100644 --- a/app/workers/run_pipeline_schedule_worker.rb +++ b/app/workers/run_pipeline_schedule_worker.rb @@ -11,16 +11,14 @@ class RunPipelineScheduleWorker # rubocop:disable Scalability/IdempotentWorker queue_namespace :pipeline_creation feature_category :continuous_integration - # rubocop: disable CodeReuse/ActiveRecord def perform(schedule_id, user_id) - schedule = Ci::PipelineSchedule.find_by(id: schedule_id) - user = User.find_by(id: user_id) + schedule = Ci::PipelineSchedule.find_by_id(schedule_id) + user = User.find_by_id(user_id) return unless schedule && user run_pipeline_schedule(schedule, user) end - # rubocop: enable CodeReuse/ActiveRecord def run_pipeline_schedule(schedule, user) Ci::CreatePipelineService.new(schedule.project, diff --git a/app/workers/ssh_keys/expired_notification_worker.rb b/app/workers/ssh_keys/expired_notification_worker.rb index d8553b5a9a2..dc1efce51ce 100644 --- a/app/workers/ssh_keys/expired_notification_worker.rb +++ b/app/workers/ssh_keys/expired_notification_worker.rb @@ -29,7 +29,7 @@ module SshKeys ) ]) - scope = Key.expired_and_not_notified.order(order) + scope = Key.expired_today_and_not_notified.order(order) iterator = Gitlab::Pagination::Keyset::Iterator.new(scope: scope, use_union_optimization: true) iterator.each_batch(of: BATCH_SIZE) do |relation| @@ -37,7 +37,7 @@ module SshKeys users.each do |user| with_context(user: user) do - Keys::ExpiryNotificationService.new(user, { keys: user.expired_and_unnotified_keys, expiring_soon: false }).execute + Keys::ExpiryNotificationService.new(user, { keys: user.expired_today_and_unnotified_keys, expiring_soon: false }).execute end end end diff --git a/app/workers/tasks_to_be_done/create_worker.rb b/app/workers/tasks_to_be_done/create_worker.rb new file mode 100644 index 00000000000..0953f190fd0 --- /dev/null +++ b/app/workers/tasks_to_be_done/create_worker.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module TasksToBeDone + class CreateWorker + include ApplicationWorker + + data_consistency :always + idempotent! + feature_category :onboarding + urgency :low + worker_resource_boundary :cpu + + def perform(member_task_id, current_user_id, assignee_ids = []) + member_task = MemberTask.find(member_task_id) + current_user = User.find(current_user_id) + project = member_task.project + + member_task.tasks_to_be_done.each do |task| + service_class(task) + .new(project: project, current_user: current_user, assignee_ids: assignee_ids) + .execute + end + end + + private + + def service_class(task) + "TasksToBeDone::Create#{task.to_s.camelize}TaskService".constantize + end + end +end diff --git a/app/workers/update_highest_role_worker.rb b/app/workers/update_highest_role_worker.rb index d5df46c172b..064b8203d4d 100644 --- a/app/workers/update_highest_role_worker.rb +++ b/app/workers/update_highest_role_worker.rb @@ -13,17 +13,15 @@ class UpdateHighestRoleWorker idempotent! - # rubocop: disable CodeReuse/ActiveRecord def perform(user_id) - user = User.find_by(id: user_id) + user = User.find_by_id(user_id) return unless user.present? if user.active? && user.human? && !user.internal? Users::UpdateHighestMemberRoleService.new(user).execute else - UserHighestRole.where(user_id: user_id).delete_all + UserHighestRole.where(user_id: user_id).delete_all # rubocop: disable CodeReuse/ActiveRecord end end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb index 421a6e47425..5c96257cb63 100644 --- a/app/workers/update_merge_requests_worker.rb +++ b/app/workers/update_merge_requests_worker.rb @@ -13,15 +13,13 @@ class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker weight 3 loggable_arguments 2, 3, 4 - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, user_id, oldrev, newrev, ref) - project = Project.find_by(id: project_id) + project = Project.find_by_id(project_id) return unless project - user = User.find_by(id: user_id) + user = User.find_by_id(user_id) return unless user MergeRequests::RefreshService.new(project: project, current_user: user).execute(oldrev, newrev, ref) end - # rubocop: enable CodeReuse/ActiveRecord end diff --git a/app/workers/update_project_statistics_worker.rb b/app/workers/update_project_statistics_worker.rb index 4a32753ac70..45a6cc8f476 100644 --- a/app/workers/update_project_statistics_worker.rb +++ b/app/workers/update_project_statistics_worker.rb @@ -13,11 +13,9 @@ class UpdateProjectStatisticsWorker # rubocop:disable Scalability/IdempotentWork # project_id - The ID of the project for which to flush the cache. # statistics - An Array containing columns from ProjectStatistics to # refresh, if empty all columns will be refreshed - # rubocop: disable CodeReuse/ActiveRecord def perform(project_id, statistics = []) - project = Project.find_by(id: project_id) + project = Project.find_by_id(project_id) Projects::UpdateStatisticsService.new(project, nil, statistics: statistics).execute end - # rubocop: enable CodeReuse/ActiveRecord end |