From 33795139ea8e72756bee3675b4e16387425e6ab1 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Wed, 19 Feb 2020 18:09:10 +0000 Subject: [PATCH] Add latest changes from gitlab-org/gitlab@master --- .../boards/components/boards_selector.vue | 18 -- .../javascripts/boards/stores/boards_store.js | 2 - app/assets/stylesheets/framework/buttons.scss | 7 +- app/models/concerns/milestone_eventable.rb | 9 + app/models/concerns/resource_event_tools.rb | 31 +++ app/models/issue.rb | 1 + app/models/merge_request.rb | 1 + app/models/milestone_note.rb | 49 +++++ app/models/resource_label_event.rb | 21 +- app/models/resource_milestone_event.rb | 30 +++ .../issuable/clone/attributes_rewriter.rb | 18 ++ .../issuable/common_system_notes_service.rb | 17 +- .../change_milestone_service.rb | 50 +++++ .../merge_into_notes_service.rb | 9 +- ...nthetic_milestone_notes_builder_service.rb | 31 +++ app/views/dashboard/todos/_todo.html.haml | 12 +- app/views/dashboard/todos/index.html.haml | 8 +- app/workers/admin_email_worker.rb | 2 +- app/workers/all_queues.yml | 180 ++++++++++++++++++ app/workers/archive_trace_worker.rb | 2 +- app/workers/authorized_projects_worker.rb | 2 +- app/workers/auto_devops/disable_worker.rb | 2 +- app/workers/auto_merge_process_worker.rb | 2 +- app/workers/background_migration_worker.rb | 24 +-- app/workers/build_coverage_worker.rb | 2 +- app/workers/build_finished_worker.rb | 2 +- app/workers/build_hooks_worker.rb | 2 +- app/workers/build_queue_worker.rb | 2 +- app/workers/build_success_worker.rb | 2 +- app/workers/build_trace_sections_worker.rb | 2 +- app/workers/chaos/cpu_spin_worker.rb | 2 +- app/workers/chaos/db_spin_worker.rb | 2 +- app/workers/chaos/kill_worker.rb | 2 +- app/workers/chaos/leak_mem_worker.rb | 2 +- app/workers/chaos/sleep_worker.rb | 2 +- app/workers/chat_notification_worker.rb | 2 +- app/workers/ci/archive_traces_cron_worker.rb | 2 +- app/workers/ci/build_prepare_worker.rb | 2 +- app/workers/ci/build_schedule_worker.rb | 2 +- .../ci/build_trace_chunk_flush_worker.rb | 2 +- .../create_cross_project_pipeline_worker.rb | 2 +- .../ci/pipeline_bridge_status_worker.rb | 2 +- ...ign_resource_from_resource_group_worker.rb | 2 +- .../cleanup_container_repository_worker.rb | 2 +- app/workers/cluster_configure_istio_worker.rb | 2 +- app/workers/cluster_configure_worker.rb | 2 +- app/workers/cluster_install_app_worker.rb | 2 +- app/workers/cluster_patch_app_worker.rb | 2 +- .../cluster_project_configure_worker.rb | 2 +- app/workers/cluster_provision_worker.rb | 2 +- app/workers/cluster_upgrade_app_worker.rb | 2 +- ...luster_wait_for_app_installation_worker.rb | 2 +- ...ster_wait_for_ingress_ip_address_worker.rb | 2 +- .../applications/activate_service_worker.rb | 2 +- .../applications/deactivate_service_worker.rb | 2 +- .../clusters/applications/uninstall_worker.rb | 2 +- .../wait_for_uninstall_app_worker.rb | 2 +- app/workers/clusters/cleanup/app_worker.rb | 2 +- .../cleanup/project_namespace_worker.rb | 2 +- .../cleanup/service_account_worker.rb | 2 +- app/workers/concerns/worker_attributes.rb | 8 + .../container_expiration_policy_worker.rb | 2 +- app/workers/create_commit_signature_worker.rb | 2 +- app/workers/create_evidence_worker.rb | 2 +- app/workers/create_note_diff_file_worker.rb | 2 +- app/workers/create_pipeline_worker.rb | 2 +- .../delete_container_repository_worker.rb | 2 +- app/workers/delete_diff_files_worker.rb | 2 +- app/workers/delete_merged_branches_worker.rb | 2 +- app/workers/delete_stored_files_worker.rb | 2 +- app/workers/delete_user_worker.rb | 2 +- app/workers/deployments/finished_worker.rb | 2 +- .../deployments/forward_deployment_worker.rb | 2 +- app/workers/deployments/success_worker.rb | 2 +- .../detect_repository_languages_worker.rb | 2 +- app/workers/email_receiver_worker.rb | 2 +- app/workers/emails_on_push_worker.rb | 2 +- .../environments/auto_stop_cron_worker.rb | 2 +- .../error_tracking_issue_link_worker.rb | 2 +- app/workers/expire_build_artifacts_worker.rb | 2 +- .../expire_build_instance_artifacts_worker.rb | 2 +- app/workers/expire_job_cache_worker.rb | 1 + app/workers/expire_pipeline_cache_worker.rb | 2 +- app/workers/file_hook_worker.rb | 2 +- app/workers/git_garbage_collect_worker.rb | 2 +- .../github_import/advance_stage_worker.rb | 2 +- .../github_import/import_diff_note_worker.rb | 2 +- .../github_import/import_issue_worker.rb | 2 +- .../github_import/import_lfs_object_worker.rb | 2 +- .../github_import/import_note_worker.rb | 2 +- .../import_pull_request_worker.rb | 2 +- .../refresh_import_jid_worker.rb | 2 +- .../stage/finish_import_worker.rb | 2 +- .../stage/import_base_data_worker.rb | 2 +- .../import_issues_and_diff_notes_worker.rb | 2 +- .../stage/import_lfs_objects_worker.rb | 2 +- .../stage/import_notes_worker.rb | 2 +- .../stage/import_pull_requests_worker.rb | 2 +- .../stage/import_repository_worker.rb | 2 +- .../gitlab/phabricator_import/base_worker.rb | 2 +- .../phabricator_import/import_tasks_worker.rb | 2 +- app/workers/gitlab_shell_worker.rb | 2 +- app/workers/gitlab_usage_ping_worker.rb | 2 +- app/workers/group_destroy_worker.rb | 2 +- app/workers/group_export_worker.rb | 2 +- app/workers/group_import_worker.rb | 2 +- app/workers/hashed_storage/base_worker.rb | 2 +- app/workers/hashed_storage/migrator_worker.rb | 2 +- .../hashed_storage/project_migrate_worker.rb | 2 +- .../hashed_storage/project_rollback_worker.rb | 2 +- .../hashed_storage/rollbacker_worker.rb | 2 +- .../import_export_project_cleanup_worker.rb | 2 +- app/workers/import_issues_csv_worker.rb | 2 +- .../process_alert_worker.rb | 2 +- .../invalid_gpg_signature_update_worker.rb | 2 +- app/workers/irker_worker.rb | 2 +- app/workers/issue_due_scheduler_worker.rb | 2 +- .../mail_scheduler/issue_due_worker.rb | 2 +- .../notification_service_worker.rb | 2 +- ...merge_request_mergeability_check_worker.rb | 2 +- app/workers/merge_worker.rb | 2 +- app/workers/migrate_external_diffs_worker.rb | 2 +- .../namespaceless_project_destroy_worker.rb | 2 +- .../prune_aggregation_schedules_worker.rb | 2 +- .../namespaces/root_statistics_worker.rb | 2 +- .../namespaces/schedule_aggregation_worker.rb | 2 +- app/workers/new_issue_worker.rb | 2 +- app/workers/new_merge_request_worker.rb | 2 +- app/workers/new_note_worker.rb | 2 +- app/workers/new_release_worker.rb | 2 +- app/workers/object_pool/create_worker.rb | 2 +- app/workers/object_pool/destroy_worker.rb | 2 +- app/workers/object_pool/join_worker.rb | 2 +- .../object_pool/schedule_join_worker.rb | 2 +- .../object_storage/background_move_worker.rb | 2 +- .../object_storage/migrate_uploads_worker.rb | 2 + .../pages_domain_removal_cron_worker.rb | 2 +- .../pages_domain_ssl_renewal_cron_worker.rb | 2 +- .../pages_domain_ssl_renewal_worker.rb | 2 +- .../pages_domain_verification_cron_worker.rb | 2 +- .../pages_domain_verification_worker.rb | 2 +- app/workers/pages_worker.rb | 2 +- .../personal_access_tokens/expiring_worker.rb | 2 +- app/workers/pipeline_hooks_worker.rb | 2 +- app/workers/pipeline_metrics_worker.rb | 2 +- app/workers/pipeline_notification_worker.rb | 2 +- app/workers/pipeline_process_worker.rb | 2 +- app/workers/pipeline_schedule_worker.rb | 2 +- app/workers/pipeline_success_worker.rb | 2 +- app/workers/pipeline_update_worker.rb | 2 +- app/workers/post_receive.rb | 2 +- app/workers/process_commit_worker.rb | 2 +- app/workers/project_cache_worker.rb | 2 +- .../project_daily_statistics_worker.rb | 2 +- app/workers/project_destroy_worker.rb | 2 +- app/workers/project_export_worker.rb | 2 +- app/workers/project_service_worker.rb | 2 +- .../propagate_service_template_worker.rb | 2 +- app/workers/prune_old_events_worker.rb | 2 +- app/workers/prune_web_hook_logs_worker.rb | 2 +- app/workers/reactive_caching_worker.rb | 2 +- app/workers/rebase_worker.rb | 2 +- .../remote_mirror_notification_worker.rb | 2 +- .../remove_expired_group_links_worker.rb | 2 +- app/workers/remove_expired_members_worker.rb | 2 +- .../remove_unreferenced_lfs_objects_worker.rb | 2 +- .../repository_archive_cache_worker.rb | 2 +- app/workers/repository_check/batch_worker.rb | 2 +- app/workers/repository_check/clear_worker.rb | 2 +- .../repository_check/dispatch_worker.rb | 2 +- .../single_repository_worker.rb | 2 +- app/workers/repository_cleanup_worker.rb | 2 +- app/workers/repository_fork_worker.rb | 2 +- app/workers/repository_import_worker.rb | 2 +- .../repository_remove_remote_worker.rb | 2 +- .../repository_update_remote_mirror_worker.rb | 2 +- app/workers/requests_profiles_worker.rb | 2 +- app/workers/run_pipeline_schedule_worker.rb | 2 +- .../schedule_migrate_external_diffs_worker.rb | 2 +- .../self_monitoring_project_create_worker.rb | 2 +- .../self_monitoring_project_delete_worker.rb | 2 +- app/workers/stage_update_worker.rb | 2 +- app/workers/stuck_ci_jobs_worker.rb | 2 +- app/workers/stuck_import_jobs_worker.rb | 2 +- app/workers/stuck_merge_jobs_worker.rb | 2 +- app/workers/system_hook_push_worker.rb | 2 +- .../confidential_issue_worker.rb | 2 +- .../todos_destroyer/entity_leave_worker.rb | 2 +- .../todos_destroyer/group_private_worker.rb | 2 +- .../private_features_worker.rb | 2 +- .../todos_destroyer/project_private_worker.rb | 2 +- app/workers/trending_projects_worker.rb | 2 +- .../update_external_pull_requests_worker.rb | 2 +- ..._head_pipeline_for_merge_request_worker.rb | 2 +- app/workers/update_merge_requests_worker.rb | 2 +- .../update_project_statistics_worker.rb | 2 +- app/workers/upload_checksum_worker.rb | 2 +- .../wait_for_cluster_creation_worker.rb | 2 +- app/workers/web_hook_worker.rb | 2 +- ...tmr-write-resource-milestone-events-pd.yml | 5 + changelogs/unreleased/ak-rescue-error.yml | 5 + ...te-fa-spinner-in-views-dashboard-todos.yml | 5 + doc/development/background_migrations.md | 11 +- lib/gitlab/database/migration_helpers.rb | 42 +++- lib/gitlab/sidekiq_config/dummy_worker.rb | 1 + lib/gitlab/sidekiq_config/worker.rb | 5 +- locale/gitlab.pot | 3 + rubocop/cop/migration/schedule_async.rb | 54 ++++++ rubocop/cop/scalability/idempotent_worker.rb | 59 ++++++ rubocop/migration_helpers.rb | 4 + .../projects/milestones_controller_spec.rb | 4 + spec/factories/resource_milestone_event.rb | 12 ++ .../gitlab/database/migration_helpers_spec.rb | 56 ++++++ spec/lib/gitlab/import_export/all_models.yml | 2 + spec/lib/gitlab/sidekiq_config/worker_spec.rb | 9 +- spec/models/milestone_note_spec.rb | 18 ++ spec/models/resource_milestone_event_spec.rb | 55 ++++++ .../cop/migration/schedule_async_spec.rb | 152 +++++++++++++++ .../cop/scalability/idempotent_worker_spec.rb | 38 ++++ spec/rubocop/migration_helpers_spec.rb | 56 ++++++ .../clone/attributes_rewriter_spec.rb | 42 ++++ .../common_system_notes_service_spec.rb | 44 ++++- spec/services/issues/update_service_spec.rb | 8 + .../merge_requests/update_service_spec.rb | 8 + .../change_milestone_service_spec.rb | 67 +++++++ spec/spec_helper.rb | 1 + .../helpers/idempotent_worker_helper.rb | 15 ++ .../move_quick_action_shared_examples.rb | 2 + .../shared_examples/resource_events.rb | 104 ++++++++++ .../workers/idempotency_shared_examples.rb | 31 +++ .../background_migration_worker_spec.rb | 10 +- spec/workers/expire_job_cache_worker_spec.rb | 30 ++- 232 files changed, 1564 insertions(+), 277 deletions(-) create mode 100644 app/models/concerns/milestone_eventable.rb create mode 100644 app/models/concerns/resource_event_tools.rb create mode 100644 app/models/milestone_note.rb create mode 100644 app/models/resource_milestone_event.rb create mode 100644 app/services/resource_events/change_milestone_service.rb create mode 100644 app/services/resource_events/synthetic_milestone_notes_builder_service.rb create mode 100644 changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml create mode 100644 changelogs/unreleased/ak-rescue-error.yml create mode 100644 changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml create mode 100644 rubocop/cop/migration/schedule_async.rb create mode 100644 rubocop/cop/scalability/idempotent_worker.rb create mode 100644 spec/factories/resource_milestone_event.rb create mode 100644 spec/models/milestone_note_spec.rb create mode 100644 spec/models/resource_milestone_event_spec.rb create mode 100644 spec/rubocop/cop/migration/schedule_async_spec.rb create mode 100644 spec/rubocop/cop/scalability/idempotent_worker_spec.rb create mode 100644 spec/rubocop/migration_helpers_spec.rb create mode 100644 spec/services/resource_events/change_milestone_service_spec.rb create mode 100644 spec/support/helpers/idempotent_worker_helper.rb create mode 100644 spec/support/shared_examples/resource_events.rb create mode 100644 spec/support/shared_examples/workers/idempotency_shared_examples.rb diff --git a/app/assets/javascripts/boards/components/boards_selector.vue b/app/assets/javascripts/boards/components/boards_selector.vue index eeb0fbec1ed..5e8b80cd959 100644 --- a/app/assets/javascripts/boards/components/boards_selector.vue +++ b/app/assets/javascripts/boards/components/boards_selector.vue @@ -110,14 +110,6 @@ export default { board.name.toLowerCase().includes(this.filterTerm.toLowerCase()), ); }, - reload: { - get() { - return this.state.reload; - }, - set(newValue) { - this.state.reload = newValue; - }, - }, board() { return this.state.currentBoard; }, @@ -142,16 +134,6 @@ export default { this.scrollFadeInitialized = false; this.$nextTick(this.setScrollFade); }, - reload() { - if (this.reload) { - this.boards = []; - this.recentBoards = []; - this.loading = true; - this.reload = false; - - this.loadBoards(false); - } - }, }, created() { boardsStore.setCurrentBoard(this.currentBoard); diff --git a/app/assets/javascripts/boards/stores/boards_store.js b/app/assets/javascripts/boards/stores/boards_store.js index e5ce8b70a4f..f233228614f 100644 --- a/app/assets/javascripts/boards/stores/boards_store.js +++ b/app/assets/javascripts/boards/stores/boards_store.js @@ -30,7 +30,6 @@ const boardsStore = { labels: [], }, currentPage: '', - reload: false, endpoints: {}, }, detail: { @@ -61,7 +60,6 @@ const boardsStore = { }; }, showPage(page) { - this.state.reload = false; this.state.currentPage = page; }, addList(listObj, defaultAvatar) { diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 1b549c0a4f0..ecbc5fa9351 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -371,8 +371,11 @@ } .btn-loading { - &:not(.disabled) .fa { - display: none; + &:not(.disabled) { + .fa, + .spinner { + display: none; + } } .fa { diff --git a/app/models/concerns/milestone_eventable.rb b/app/models/concerns/milestone_eventable.rb new file mode 100644 index 00000000000..17a02c9d3e4 --- /dev/null +++ b/app/models/concerns/milestone_eventable.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +module MilestoneEventable + extend ActiveSupport::Concern + + included do + has_many :resource_milestone_events + end +end diff --git a/app/models/concerns/resource_event_tools.rb b/app/models/concerns/resource_event_tools.rb new file mode 100644 index 00000000000..7226b9573e1 --- /dev/null +++ b/app/models/concerns/resource_event_tools.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module ResourceEventTools + extend ActiveSupport::Concern + + included do + belongs_to :user + + validates :user, presence: { unless: :importing? }, on: :create + + validate :exactly_one_issuable + + scope :created_after, ->(time) { where('created_at > ?', time) } + end + + def exactly_one_issuable + issuable_count = self.class.issuable_attrs.count { |attr| self["#{attr}_id"] } + + return true if issuable_count == 1 + + # if none of issuable IDs is set, check explicitly if nested issuable + # object is set, this is used during project import + if issuable_count == 0 && importing? + issuable_count = self.class.issuable_attrs.count { |attr| self.public_send(attr) } # rubocop:disable GitlabSecurity/PublicSend + + return true if issuable_count == 1 + end + + errors.add(:base, "Exactly one of #{self.class.issuable_attrs.join(', ')} is required") + end +end diff --git a/app/models/issue.rb b/app/models/issue.rb index 83f9e803d42..1c191064d1a 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -15,6 +15,7 @@ class Issue < ApplicationRecord include ThrottledTouch include LabelEventable include IgnorableColumns + include MilestoneEventable DueDateStruct = Struct.new(:title, :name).freeze NoDueDate = DueDateStruct.new('No Due Date', '0').freeze diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index b469174fc63..5dda1bd8cc7 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -18,6 +18,7 @@ class MergeRequest < ApplicationRecord include DeprecatedAssignee include ShaAttribute include IgnorableColumns + include MilestoneEventable sha_attribute :squash_commit_sha diff --git a/app/models/milestone_note.rb b/app/models/milestone_note.rb new file mode 100644 index 00000000000..8ff0503502f --- /dev/null +++ b/app/models/milestone_note.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +class MilestoneNote < ::Note + attr_accessor :resource_parent, :event, :milestone + + def self.from_event(event, resource: nil, resource_parent: nil) + resource ||= event.resource + + attrs = { + system: true, + author: event.user, + created_at: event.created_at, + noteable: resource, + milestone: event.milestone, + event: event, + system_note_metadata: ::SystemNoteMetadata.new(action: 'milestone'), + resource_parent: resource_parent + } + + if resource_parent.is_a?(Project) + attrs[:project_id] = resource_parent.id + end + + MilestoneNote.new(attrs) + end + + def note + @note ||= note_text + end + + def note_html + @note_html ||= Banzai::Renderer.cacheless_render_field(self, :note, { group: group, project: project }) + end + + def project + resource_parent if resource_parent.is_a?(Project) + end + + def group + resource_parent if resource_parent.is_a?(Group) + end + + private + + def note_text(html: false) + format = milestone&.group_milestone? ? :name : :iid + milestone.nil? ? 'removed milestone' : "changed milestone to #{milestone.to_reference(project, format: format)}" + end +end diff --git a/app/models/resource_label_event.rb b/app/models/resource_label_event.rb index 98fc9e7bae8..59907f1b962 100644 --- a/app/models/resource_label_event.rb +++ b/app/models/resource_label_event.rb @@ -4,20 +4,17 @@ class ResourceLabelEvent < ApplicationRecord include Importable include Gitlab::Utils::StrongMemoize include CacheMarkdownField + include ResourceEventTools cache_markdown_field :reference - belongs_to :user belongs_to :issue belongs_to :merge_request belongs_to :label - scope :created_after, ->(time) { where('created_at > ?', time) } scope :inc_relations, -> { includes(:label, :user) } - validates :user, presence: { unless: :importing? }, on: :create validates :label, presence: { unless: :importing? }, on: :create - validate :exactly_one_issuable after_save :expire_etag_cache after_destroy :expire_etag_cache @@ -94,22 +91,6 @@ class ResourceLabelEvent < ApplicationRecord end end - def exactly_one_issuable - issuable_count = self.class.issuable_attrs.count { |attr| self["#{attr}_id"] } - - return true if issuable_count == 1 - - # if none of issuable IDs is set, check explicitly if nested issuable - # object is set, this is used during project import - if issuable_count == 0 && importing? - issuable_count = self.class.issuable_attrs.count { |attr| self.public_send(attr) } # rubocop:disable GitlabSecurity/PublicSend - - return true if issuable_count == 1 - end - - errors.add(:base, "Exactly one of #{self.class.issuable_attrs.join(', ')} is required") - end - def expire_etag_cache issuable.expire_note_etag_cache end diff --git a/app/models/resource_milestone_event.rb b/app/models/resource_milestone_event.rb new file mode 100644 index 00000000000..ba43a1ee363 --- /dev/null +++ b/app/models/resource_milestone_event.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class ResourceMilestoneEvent < ApplicationRecord + include Gitlab::Utils::StrongMemoize + include Importable + include ResourceEventTools + + belongs_to :issue + belongs_to :merge_request + belongs_to :milestone + + scope :by_issue, ->(issue) { where(issue_id: issue.id) } + scope :by_merge_request, ->(merge_request) { where(merge_request_id: merge_request.id) } + + enum action: { + add: 1, + remove: 2 + } + + # state is used for issue and merge request states. + enum state: Issue.available_states.merge(MergeRequest.available_states) + + def self.issuable_attrs + %i(issue merge_request).freeze + end + + def resource + issue || merge_request + end +end diff --git a/app/services/issuable/clone/attributes_rewriter.rb b/app/services/issuable/clone/attributes_rewriter.rb index 2b436f6322c..135ab011d69 100644 --- a/app/services/issuable/clone/attributes_rewriter.rb +++ b/app/services/issuable/clone/attributes_rewriter.rb @@ -19,6 +19,7 @@ module Issuable copy_resource_label_events copy_resource_weight_events + copy_resource_milestone_events end private @@ -65,6 +66,23 @@ module Issuable end end + def copy_resource_milestone_events + entity_key = new_entity.class.name.underscore.foreign_key + + copy_events(ResourceMilestoneEvent.table_name, original_entity.resource_milestone_events) do |event| + matching_destination_milestone = matching_milestone(event.milestone.title) + + if matching_destination_milestone.present? + event.attributes + .except('id', 'reference', 'reference_html') + .merge(entity_key => new_entity.id, + 'milestone_id' => matching_destination_milestone.id, + 'action' => ResourceMilestoneEvent.actions[event.action], + 'state' => ResourceMilestoneEvent.states[event.state]) + end + end + end + def copy_events(table_name, events_to_copy) events_to_copy.find_in_batches do |batch| events = batch.map do |event| diff --git a/app/services/issuable/common_system_notes_service.rb b/app/services/issuable/common_system_notes_service.rb index 846b881e819..c53e19c922a 100644 --- a/app/services/issuable/common_system_notes_service.rb +++ b/app/services/issuable/common_system_notes_service.rb @@ -22,13 +22,17 @@ module Issuable end create_due_date_note if issuable.previous_changes.include?('due_date') - create_milestone_note if issuable.previous_changes.include?('milestone_id') + create_milestone_note if has_milestone_changes? create_labels_note(old_labels) if old_labels && issuable.labels != old_labels end end private + def has_milestone_changes? + issuable.previous_changes.include?('milestone_id') + end + def handle_time_tracking_note if issuable.previous_changes.include?('time_estimate') create_time_estimate_note @@ -95,7 +99,16 @@ module Issuable end def create_milestone_note - SystemNoteService.change_milestone(issuable, issuable.project, current_user, issuable.milestone) + if milestone_changes_tracking_enabled? + # Creates a synthetic note + ResourceEvents::ChangeMilestoneService.new(resource: issuable, user: current_user).execute + else + SystemNoteService.change_milestone(issuable, issuable.project, current_user, issuable.milestone) + end + end + + def milestone_changes_tracking_enabled? + ::Feature.enabled?(:track_resource_milestone_change_events, issuable.project) end def create_due_date_note diff --git a/app/services/resource_events/change_milestone_service.rb b/app/services/resource_events/change_milestone_service.rb new file mode 100644 index 00000000000..bad7d002c65 --- /dev/null +++ b/app/services/resource_events/change_milestone_service.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module ResourceEvents + class ChangeMilestoneService + attr_reader :resource, :user, :event_created_at, :resource_args + + def initialize(resource:, user:, created_at: Time.now) + @resource = resource + @user = user + @event_created_at = created_at + + @resource_args = { + user_id: user.id, + created_at: event_created_at + } + end + + def execute + args = build_resource_args + + action = if milestone.nil? + :remove + else + :add + end + + record = args.merge(milestone_id: milestone&.id, action: ResourceMilestoneEvent.actions[action]) + + create_event(record) + end + + private + + def milestone + resource&.milestone + end + + def create_event(record) + ResourceMilestoneEvent.create(record) + + resource.expire_note_etag_cache + end + + def build_resource_args + key = resource.class.name.underscore.foreign_key + + resource_args.merge(key => resource.id, state: ResourceMilestoneEvent.states[resource.state]) + end + end +end diff --git a/app/services/resource_events/merge_into_notes_service.rb b/app/services/resource_events/merge_into_notes_service.rb index 47948fcff6e..4aa9bb80229 100644 --- a/app/services/resource_events/merge_into_notes_service.rb +++ b/app/services/resource_events/merge_into_notes_service.rb @@ -9,6 +9,11 @@ module ResourceEvents class MergeIntoNotesService include Gitlab::Utils::StrongMemoize + SYNTHETIC_NOTE_BUILDER_SERVICES = [ + SyntheticLabelNotesBuilderService, + SyntheticMilestoneNotesBuilderService + ].freeze + attr_reader :resource, :current_user, :params def initialize(resource, current_user, params = {}) @@ -24,7 +29,9 @@ module ResourceEvents private def synthetic_notes - SyntheticLabelNotesBuilderService.new(resource, current_user, params).execute + SYNTHETIC_NOTE_BUILDER_SERVICES.flat_map do |service| + service.new(resource, current_user, params).execute + end end end end diff --git a/app/services/resource_events/synthetic_milestone_notes_builder_service.rb b/app/services/resource_events/synthetic_milestone_notes_builder_service.rb new file mode 100644 index 00000000000..ad58417834e --- /dev/null +++ b/app/services/resource_events/synthetic_milestone_notes_builder_service.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# We store events about resource milestone changes in a separate table, +# but we still want to display notes about milestone changes +# as classic system notes in UI. This service generates "synthetic" notes for +# milestone event changes. + +module ResourceEvents + class SyntheticMilestoneNotesBuilderService < BaseSyntheticNotesBuilderService + private + + def synthetic_notes + return [] unless tracking_enabled? + + milestone_change_events.map do |event| + MilestoneNote.from_event(event, resource: resource, resource_parent: resource_parent) + end + end + + def milestone_change_events + return [] unless resource.respond_to?(:resource_milestone_events) + + events = resource.resource_milestone_events.includes(user: :status) # rubocop: disable CodeReuse/ActiveRecord + since_fetch_at(events) + end + + def tracking_enabled? + ::Feature.enabled?(:track_resource_milestone_change_events, resource.project) + end + end +end diff --git a/app/views/dashboard/todos/_todo.html.haml b/app/views/dashboard/todos/_todo.html.haml index fdb71d3a221..f5ffe8f2e36 100644 --- a/app/views/dashboard/todos/_todo.html.haml +++ b/app/views/dashboard/todos/_todo.html.haml @@ -48,14 +48,14 @@ - if todo.pending? .todo-actions - = link_to dashboard_todo_path(todo), method: :delete, class: 'btn btn-loading js-done-todo', data: { href: dashboard_todo_path(todo) } do + = link_to dashboard_todo_path(todo), method: :delete, class: 'btn btn-loading d-flex align-items-center js-done-todo', data: { href: dashboard_todo_path(todo) } do Done - = icon('spinner spin') - = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do + %span.spinner.ml-1 + = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading d-flex align-items-center js-undo-todo hidden', data: { href: restore_dashboard_todo_path(todo) } do Undo - = icon('spinner spin') + %span.spinner.ml-1 - else .todo-actions - = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do + = link_to restore_dashboard_todo_path(todo), method: :patch, class: 'btn btn-loading d-flex align-items-center js-add-todo', data: { href: restore_dashboard_todo_path(todo) } do Add a To Do - = icon('spinner spin') + %span.spinner.ml-1 diff --git a/app/views/dashboard/todos/index.html.haml b/app/views/dashboard/todos/index.html.haml index 731e763f2be..cfc637592d3 100644 --- a/app/views/dashboard/todos/index.html.haml +++ b/app/views/dashboard/todos/index.html.haml @@ -26,12 +26,12 @@ .nav-controls - if @todos.any?(&:pending?) .append-right-default - = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do + = link_to destroy_all_dashboard_todos_path(todos_filter_params), class: 'btn btn-loading d-flex align-items-center js-todos-mark-all', method: :delete, data: { href: destroy_all_dashboard_todos_path(todos_filter_params) } do Mark all as done - = icon('spinner spin') - = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do + %span.spinner.ml-1 + = link_to bulk_restore_dashboard_todos_path, class: 'btn btn-loading d-flex align-items-center js-todos-undo-all hidden', method: :patch , data: { href: bulk_restore_dashboard_todos_path(todos_filter_params) } do Undo mark all as done - = icon('spinner spin') + %span.spinner.ml-1 .todos-filters .issues-details-filters.row-content-block.second-block diff --git a/app/workers/admin_email_worker.rb b/app/workers/admin_email_worker.rb index 9388b1014ac..c84ac60d777 100644 --- a/app/workers/admin_email_worker.rb +++ b/app/workers/admin_email_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class AdminEmailWorker +class AdminEmailWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index 459872965f8..e8682769720 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -9,1077 +9,1257 @@ :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: auto_merge:auto_merge_process :feature_category: :continuous_delivery :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: chaos:chaos_cpu_spin :feature_category: :chaos_engineering :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: chaos:chaos_db_spin :feature_category: :chaos_engineering :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: chaos:chaos_kill :feature_category: :chaos_engineering :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: chaos:chaos_leak_mem :feature_category: :chaos_engineering :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: chaos:chaos_sleep :feature_category: :chaos_engineering :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: container_repository:cleanup_container_repository :feature_category: :container_registry :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: container_repository:delete_container_repository :feature_category: :container_registry :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:admin_email :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:ci_archive_traces_cron :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:container_expiration_policy :feature_category: :container_registry :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:environments_auto_stop_cron :feature_category: :continuous_delivery :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:expire_build_artifacts :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:gitlab_usage_ping :feature_category: :collection :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:import_export_project_cleanup :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:issue_due_scheduler :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:namespaces_prune_aggregation_schedules :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: cronjob:pages_domain_removal_cron :feature_category: :pages :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: cronjob:pages_domain_ssl_renewal_cron :feature_category: :pages :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:pages_domain_verification_cron :feature_category: :pages :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:personal_access_tokens_expiring :feature_category: :authentication_and_authorization :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:pipeline_schedule :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: cronjob:prune_old_events :feature_category: :users :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:prune_web_hook_logs :feature_category: :integrations :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:remove_expired_group_links :feature_category: :authentication_and_authorization :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:remove_expired_members :feature_category: :authentication_and_authorization :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: cronjob:remove_unreferenced_lfs_objects :feature_category: :git_lfs :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:repository_archive_cache :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:repository_check_dispatch :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:requests_profiles :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:schedule_migrate_external_diffs :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:stuck_ci_jobs :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: cronjob:stuck_import_jobs :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: cronjob:stuck_merge_jobs :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: cronjob:trending_projects :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: deployment:deployments_finished :feature_category: :continuous_delivery :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: deployment:deployments_forward_deployment :feature_category: :continuous_delivery :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 3 + :idempotent: - :name: deployment:deployments_success :feature_category: :continuous_delivery :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: gcp_cluster:cluster_configure :feature_category: :kubernetes_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_configure_istio :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_install_app :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_patch_app :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_project_configure :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_provision :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_upgrade_app :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_wait_for_app_installation :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: gcp_cluster:cluster_wait_for_ingress_ip_address :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_applications_activate_service :feature_category: :kubernetes_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_applications_deactivate_service :feature_category: :kubernetes_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_applications_uninstall :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_applications_wait_for_uninstall_app :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_cleanup_app :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_cleanup_project_namespace :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:clusters_cleanup_service_account :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gcp_cluster:wait_for_cluster_creation :feature_category: :kubernetes_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_import_diff_note :feature_category: :importers :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_import_issue :feature_category: :importers :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_import_lfs_object :feature_category: :importers :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_import_note :feature_category: :importers :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_import_pull_request :feature_category: :importers :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_refresh_import_jid :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_finish_import :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_import_base_data :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_import_issues_and_diff_notes :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_import_lfs_objects :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_import_notes :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_import_pull_requests :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_importer:github_import_stage_import_repository :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: hashed_storage:hashed_storage_migrator :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: hashed_storage:hashed_storage_project_migrate :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: hashed_storage:hashed_storage_project_rollback :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: hashed_storage:hashed_storage_rollbacker :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: incident_management:incident_management_process_alert :feature_category: :incident_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: mail_scheduler:mail_scheduler_issue_due :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: mail_scheduler:mail_scheduler_notification_service :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: notifications:new_release :feature_category: :release_orchestration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: object_pool:object_pool_create :feature_category: :gitaly :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: object_pool:object_pool_destroy :feature_category: :gitaly :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: object_pool:object_pool_join :feature_category: :gitaly :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: object_pool:object_pool_schedule_join :feature_category: :gitaly :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: object_storage:object_storage_background_move :feature_category: :not_owned :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: object_storage:object_storage_migrate_uploads :feature_category: :not_owned :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: pipeline_background:archive_trace :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: pipeline_background:ci_build_trace_chunk_flush :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: pipeline_cache:expire_job_cache :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 3 + :idempotent: true - :name: pipeline_cache:expire_pipeline_cache :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: pipeline_creation:create_pipeline :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 4 + :idempotent: - :name: pipeline_creation:run_pipeline_schedule :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 4 + :idempotent: - :name: pipeline_default:build_coverage :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 3 + :idempotent: - :name: pipeline_default:build_trace_sections :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 3 + :idempotent: - :name: pipeline_default:ci_create_cross_project_pipeline :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: pipeline_default:ci_pipeline_bridge_status :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: pipeline_default:pipeline_metrics :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 3 + :idempotent: - :name: pipeline_default:pipeline_notification :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: pipeline_hooks:build_hooks :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: pipeline_hooks:pipeline_hooks :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: pipeline_processing:build_finished :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 5 + :idempotent: - :name: pipeline_processing:build_queue :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 5 + :idempotent: - :name: pipeline_processing:build_success :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:ci_build_prepare :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:ci_build_schedule :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 5 + :idempotent: - :name: pipeline_processing:ci_resource_groups_assign_resource_from_resource_group :feature_category: :continuous_delivery :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:pipeline_process :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:pipeline_success :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:pipeline_update :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:stage_update :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: pipeline_processing:update_head_pipeline_for_merge_request :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 5 + :idempotent: - :name: repository_check:repository_check_batch :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: repository_check:repository_check_clear :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: repository_check:repository_check_single_repository :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: todos_destroyer:todos_destroyer_confidential_issue :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: todos_destroyer:todos_destroyer_entity_leave :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: todos_destroyer:todos_destroyer_group_private :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: todos_destroyer:todos_destroyer_private_features :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: todos_destroyer:todos_destroyer_project_private :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: update_namespace_statistics:namespaces_root_statistics :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: update_namespace_statistics:namespaces_schedule_aggregation :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: authorized_projects :feature_category: :authentication_and_authorization :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: background_migration :feature_category: :not_owned :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: chat_notification :feature_category: :chatops :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: create_commit_signature :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: create_evidence :feature_category: :release_governance :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: create_note_diff_file :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: default :feature_category: :has_external_dependencies: :latency_sensitive: :resource_boundary: :weight: 1 + :idempotent: - :name: delete_diff_files :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: delete_merged_branches :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: delete_stored_files :feature_category: :not_owned :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: delete_user :feature_category: :authentication_and_authorization :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: detect_repository_languages :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: email_receiver :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: emails_on_push :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: error_tracking_issue_link :feature_category: :error_tracking :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: expire_build_instance_artifacts :feature_category: :continuous_integration :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: file_hook :feature_category: :integrations :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: git_garbage_collect :feature_category: :gitaly :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: github_import_advance_stage :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: gitlab_shell :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: group_destroy :feature_category: :subgroups :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: group_export :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: group_import :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: import_issues_csv :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: invalid_gpg_signature_update :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: irker :feature_category: :integrations :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: mailers :feature_category: :has_external_dependencies: :latency_sensitive: :resource_boundary: :weight: 2 + :idempotent: - :name: merge :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 5 + :idempotent: - :name: merge_request_mergeability_check :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: migrate_external_diffs :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: namespaceless_project_destroy :feature_category: :authentication_and_authorization :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: new_issue :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: new_merge_request :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: new_note :feature_category: :issue_tracking :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 2 + :idempotent: - :name: pages :feature_category: :pages :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: pages_domain_ssl_renewal :feature_category: :pages :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: pages_domain_verification :feature_category: :pages :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: phabricator_import_import_tasks :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: post_receive :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 5 + :idempotent: - :name: process_commit :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 3 + :idempotent: - :name: project_cache :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: project_daily_statistics :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: project_destroy :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: project_export :feature_category: :importers :has_external_dependencies: :latency_sensitive: :resource_boundary: :memory :weight: 1 + :idempotent: - :name: project_service :feature_category: :integrations :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: propagate_service_template :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: reactive_caching :feature_category: :not_owned :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 1 + :idempotent: - :name: rebase :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: remote_mirror_notification :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: repository_cleanup :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: repository_fork :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: repository_import :feature_category: :importers :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: repository_remove_remote :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: repository_update_remote_mirror :feature_category: :source_code_management :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: self_monitoring_project_create :feature_category: :metrics :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: self_monitoring_project_delete :feature_category: :metrics :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 2 + :idempotent: - :name: system_hook_push :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: update_external_pull_requests :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 3 + :idempotent: - :name: update_merge_requests :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: true :resource_boundary: :cpu :weight: 3 + :idempotent: - :name: update_project_statistics :feature_category: :source_code_management :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: upload_checksum :feature_category: :geo_replication :has_external_dependencies: :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: - :name: web_hook :feature_category: :integrations :has_external_dependencies: true :latency_sensitive: :resource_boundary: :unknown :weight: 1 + :idempotent: diff --git a/app/workers/archive_trace_worker.rb b/app/workers/archive_trace_worker.rb index 66f9b8d9e80..3ddb5686bf2 100644 --- a/app/workers/archive_trace_worker.rb +++ b/app/workers/archive_trace_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ArchiveTraceWorker +class ArchiveTraceWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineBackgroundQueue diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb index 1ab2fd6023f..cd7ce386433 100644 --- a/app/workers/authorized_projects_worker.rb +++ b/app/workers/authorized_projects_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class AuthorizedProjectsWorker +class AuthorizedProjectsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker prepend WaitableWorker diff --git a/app/workers/auto_devops/disable_worker.rb b/app/workers/auto_devops/disable_worker.rb index 73ddc591505..bae08cf9e18 100644 --- a/app/workers/auto_devops/disable_worker.rb +++ b/app/workers/auto_devops/disable_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module AutoDevops - class DisableWorker + class DisableWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include AutoDevopsQueue diff --git a/app/workers/auto_merge_process_worker.rb b/app/workers/auto_merge_process_worker.rb index 1681fac3363..2599c76c900 100644 --- a/app/workers/auto_merge_process_worker.rb +++ b/app/workers/auto_merge_process_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class AutoMergeProcessWorker +class AutoMergeProcessWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :auto_merge diff --git a/app/workers/background_migration_worker.rb b/app/workers/background_migration_worker.rb index 20e2cdd7f96..231c2bcd83b 100644 --- a/app/workers/background_migration_worker.rb +++ b/app/workers/background_migration_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BackgroundMigrationWorker +class BackgroundMigrationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category_not_owned! @@ -22,17 +22,19 @@ class BackgroundMigrationWorker # class_name - The class name of the background migration to run. # arguments - The arguments to pass to the migration class. def perform(class_name, arguments = []) - should_perform, ttl = perform_and_ttl(class_name) + with_context(caller_id: class_name.to_s) do + should_perform, ttl = perform_and_ttl(class_name) - if should_perform - Gitlab::BackgroundMigration.perform(class_name, arguments) - else - # If the lease could not be obtained this means either another process is - # running a migration of this class or we ran one recently. In this case - # we'll reschedule the job in such a way that it is picked up again around - # the time the lease expires. - self.class - .perform_in(ttl || self.class.minimum_interval, class_name, arguments) + if should_perform + Gitlab::BackgroundMigration.perform(class_name, arguments) + else + # If the lease could not be obtained this means either another process is + # running a migration of this class or we ran one recently. In this case + # we'll reschedule the job in such a way that it is picked up again around + # the time the lease expires. + self.class + .perform_in(ttl || self.class.minimum_interval, class_name, arguments) + end end end diff --git a/app/workers/build_coverage_worker.rb b/app/workers/build_coverage_worker.rb index 912c53e11f8..7d893024abc 100644 --- a/app/workers/build_coverage_worker.rb +++ b/app/workers/build_coverage_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildCoverageWorker +class BuildCoverageWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/build_finished_worker.rb b/app/workers/build_finished_worker.rb index 77ce0923307..0e69aa07cc1 100644 --- a/app/workers/build_finished_worker.rb +++ b/app/workers/build_finished_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildFinishedWorker +class BuildFinishedWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb index fa55769e486..2662e991773 100644 --- a/app/workers/build_hooks_worker.rb +++ b/app/workers/build_hooks_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildHooksWorker +class BuildHooksWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/build_queue_worker.rb b/app/workers/build_queue_worker.rb index 6f75f403e6e..16d347a0e5c 100644 --- a/app/workers/build_queue_worker.rb +++ b/app/workers/build_queue_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildQueueWorker +class BuildQueueWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/build_success_worker.rb b/app/workers/build_success_worker.rb index b7dbd367fee..cb670b5bca7 100644 --- a/app/workers/build_success_worker.rb +++ b/app/workers/build_success_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildSuccessWorker +class BuildSuccessWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/build_trace_sections_worker.rb b/app/workers/build_trace_sections_worker.rb index 0641130fd64..c25f77974e9 100644 --- a/app/workers/build_trace_sections_worker.rb +++ b/app/workers/build_trace_sections_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class BuildTraceSectionsWorker +class BuildTraceSectionsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/chaos/cpu_spin_worker.rb b/app/workers/chaos/cpu_spin_worker.rb index 43a32c3274f..0b565e0d49c 100644 --- a/app/workers/chaos/cpu_spin_worker.rb +++ b/app/workers/chaos/cpu_spin_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Chaos - class CpuSpinWorker + class CpuSpinWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ChaosQueue diff --git a/app/workers/chaos/db_spin_worker.rb b/app/workers/chaos/db_spin_worker.rb index 217ddabbcb6..099660d440c 100644 --- a/app/workers/chaos/db_spin_worker.rb +++ b/app/workers/chaos/db_spin_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Chaos - class DbSpinWorker + class DbSpinWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ChaosQueue diff --git a/app/workers/chaos/kill_worker.rb b/app/workers/chaos/kill_worker.rb index 80f04db1be4..3dedd47a1f9 100644 --- a/app/workers/chaos/kill_worker.rb +++ b/app/workers/chaos/kill_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Chaos - class KillWorker + class KillWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ChaosQueue diff --git a/app/workers/chaos/leak_mem_worker.rb b/app/workers/chaos/leak_mem_worker.rb index 0caa99e0de9..b77d1a20541 100644 --- a/app/workers/chaos/leak_mem_worker.rb +++ b/app/workers/chaos/leak_mem_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Chaos - class LeakMemWorker + class LeakMemWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ChaosQueue diff --git a/app/workers/chaos/sleep_worker.rb b/app/workers/chaos/sleep_worker.rb index 7c724c4cb4e..6887258e961 100644 --- a/app/workers/chaos/sleep_worker.rb +++ b/app/workers/chaos/sleep_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Chaos - class SleepWorker + class SleepWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ChaosQueue diff --git a/app/workers/chat_notification_worker.rb b/app/workers/chat_notification_worker.rb index f23c787559f..78d4206ec1a 100644 --- a/app/workers/chat_notification_worker.rb +++ b/app/workers/chat_notification_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ChatNotificationWorker +class ChatNotificationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker TimeoutExceeded = Class.new(StandardError) diff --git a/app/workers/ci/archive_traces_cron_worker.rb b/app/workers/ci/archive_traces_cron_worker.rb index c73c7ba2dd8..0171c1d482d 100644 --- a/app/workers/ci/archive_traces_cron_worker.rb +++ b/app/workers/ci/archive_traces_cron_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class ArchiveTracesCronWorker + class ArchiveTracesCronWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/ci/build_prepare_worker.rb b/app/workers/ci/build_prepare_worker.rb index 20208c18d03..7f640633070 100644 --- a/app/workers/ci/build_prepare_worker.rb +++ b/app/workers/ci/build_prepare_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class BuildPrepareWorker + class BuildPrepareWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/ci/build_schedule_worker.rb b/app/workers/ci/build_schedule_worker.rb index e34f16f46c2..9231b40978d 100644 --- a/app/workers/ci/build_schedule_worker.rb +++ b/app/workers/ci/build_schedule_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class BuildScheduleWorker + class BuildScheduleWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/ci/build_trace_chunk_flush_worker.rb b/app/workers/ci/build_trace_chunk_flush_worker.rb index 23a11c28f9b..fe59ba896a4 100644 --- a/app/workers/ci/build_trace_chunk_flush_worker.rb +++ b/app/workers/ci/build_trace_chunk_flush_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class BuildTraceChunkFlushWorker + class BuildTraceChunkFlushWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineBackgroundQueue diff --git a/app/workers/ci/create_cross_project_pipeline_worker.rb b/app/workers/ci/create_cross_project_pipeline_worker.rb index 91e9317713e..713d0092b32 100644 --- a/app/workers/ci/create_cross_project_pipeline_worker.rb +++ b/app/workers/ci/create_cross_project_pipeline_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class CreateCrossProjectPipelineWorker + class CreateCrossProjectPipelineWorker # rubocop:disable Scalability/IdempotentWorker include ::ApplicationWorker include ::PipelineQueue diff --git a/app/workers/ci/pipeline_bridge_status_worker.rb b/app/workers/ci/pipeline_bridge_status_worker.rb index f196573deaa..e4e9d8480c2 100644 --- a/app/workers/ci/pipeline_bridge_status_worker.rb +++ b/app/workers/ci/pipeline_bridge_status_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Ci - class PipelineBridgeStatusWorker + class PipelineBridgeStatusWorker # rubocop:disable Scalability/IdempotentWorker include ::ApplicationWorker include ::PipelineQueue 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 62233d19516..8063e34a1b8 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 @@ -2,7 +2,7 @@ module Ci module ResourceGroups - class AssignResourceFromResourceGroupWorker + class AssignResourceFromResourceGroupWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/cleanup_container_repository_worker.rb b/app/workers/cleanup_container_repository_worker.rb index 83397a1dda2..c3fac453e73 100644 --- a/app/workers/cleanup_container_repository_worker.rb +++ b/app/workers/cleanup_container_repository_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CleanupContainerRepositoryWorker +class CleanupContainerRepositoryWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :container_repository diff --git a/app/workers/cluster_configure_istio_worker.rb b/app/workers/cluster_configure_istio_worker.rb index dfdd408f286..ec6bdfbd6b6 100644 --- a/app/workers/cluster_configure_istio_worker.rb +++ b/app/workers/cluster_configure_istio_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterConfigureIstioWorker +class ClusterConfigureIstioWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/cluster_configure_worker.rb b/app/workers/cluster_configure_worker.rb index e7a4797e68e..f9364ab7144 100644 --- a/app/workers/cluster_configure_worker.rb +++ b/app/workers/cluster_configure_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterConfigureWorker +class ClusterConfigureWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/cluster_install_app_worker.rb b/app/workers/cluster_install_app_worker.rb index 0e075b295dd..002932a0fa5 100644 --- a/app/workers/cluster_install_app_worker.rb +++ b/app/workers/cluster_install_app_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterInstallAppWorker +class ClusterInstallAppWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/cluster_patch_app_worker.rb b/app/workers/cluster_patch_app_worker.rb index 3f95a764567..f75004aa3e5 100644 --- a/app/workers/cluster_patch_app_worker.rb +++ b/app/workers/cluster_patch_app_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterPatchAppWorker +class ClusterPatchAppWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/cluster_project_configure_worker.rb b/app/workers/cluster_project_configure_worker.rb index 614029c2b5c..b68df01dc7a 100644 --- a/app/workers/cluster_project_configure_worker.rb +++ b/app/workers/cluster_project_configure_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterProjectConfigureWorker +class ClusterProjectConfigureWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/cluster_provision_worker.rb b/app/workers/cluster_provision_worker.rb index c34284319dd..cb750f3021e 100644 --- a/app/workers/cluster_provision_worker.rb +++ b/app/workers/cluster_provision_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterProvisionWorker +class ClusterProvisionWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/cluster_upgrade_app_worker.rb b/app/workers/cluster_upgrade_app_worker.rb index cd06f0a2224..99f48415f08 100644 --- a/app/workers/cluster_upgrade_app_worker.rb +++ b/app/workers/cluster_upgrade_app_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterUpgradeAppWorker +class ClusterUpgradeAppWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/cluster_wait_for_app_installation_worker.rb b/app/workers/cluster_wait_for_app_installation_worker.rb index 7155dc6f835..e098c3b86b5 100644 --- a/app/workers/cluster_wait_for_app_installation_worker.rb +++ b/app/workers/cluster_wait_for_app_installation_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterWaitForAppInstallationWorker +class ClusterWaitForAppInstallationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/cluster_wait_for_ingress_ip_address_worker.rb b/app/workers/cluster_wait_for_ingress_ip_address_worker.rb index 14b1651cc72..c7336ee515d 100644 --- a/app/workers/cluster_wait_for_ingress_ip_address_worker.rb +++ b/app/workers/cluster_wait_for_ingress_ip_address_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ClusterWaitForIngressIpAddressWorker +class ClusterWaitForIngressIpAddressWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/clusters/applications/activate_service_worker.rb b/app/workers/clusters/applications/activate_service_worker.rb index 4f285d55162..abd7f8eaea4 100644 --- a/app/workers/clusters/applications/activate_service_worker.rb +++ b/app/workers/clusters/applications/activate_service_worker.rb @@ -2,7 +2,7 @@ module Clusters module Applications - class ActivateServiceWorker + class ActivateServiceWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/clusters/applications/deactivate_service_worker.rb b/app/workers/clusters/applications/deactivate_service_worker.rb index 2c560cc998c..fecbb6dde45 100644 --- a/app/workers/clusters/applications/deactivate_service_worker.rb +++ b/app/workers/clusters/applications/deactivate_service_worker.rb @@ -2,7 +2,7 @@ module Clusters module Applications - class DeactivateServiceWorker + class DeactivateServiceWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/clusters/applications/uninstall_worker.rb b/app/workers/clusters/applications/uninstall_worker.rb index 6180998c8d9..977a25e8442 100644 --- a/app/workers/clusters/applications/uninstall_worker.rb +++ b/app/workers/clusters/applications/uninstall_worker.rb @@ -2,7 +2,7 @@ module Clusters module Applications - class UninstallWorker + class UninstallWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb b/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb index 7907aa8dfff..a486cfa90b7 100644 --- a/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb +++ b/app/workers/clusters/applications/wait_for_uninstall_app_worker.rb @@ -2,7 +2,7 @@ module Clusters module Applications - class WaitForUninstallAppWorker + class WaitForUninstallAppWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue include ClusterApplications diff --git a/app/workers/clusters/cleanup/app_worker.rb b/app/workers/clusters/cleanup/app_worker.rb index 8b2fddd3164..1d01cec174b 100644 --- a/app/workers/clusters/cleanup/app_worker.rb +++ b/app/workers/clusters/cleanup/app_worker.rb @@ -2,7 +2,7 @@ module Clusters module Cleanup - class AppWorker + class AppWorker # rubocop:disable Scalability/IdempotentWorker include ClusterCleanupMethods def perform(cluster_id, execution_count = 0) diff --git a/app/workers/clusters/cleanup/project_namespace_worker.rb b/app/workers/clusters/cleanup/project_namespace_worker.rb index 8a7fbf0fde7..a7a951f2937 100644 --- a/app/workers/clusters/cleanup/project_namespace_worker.rb +++ b/app/workers/clusters/cleanup/project_namespace_worker.rb @@ -2,7 +2,7 @@ module Clusters module Cleanup - class ProjectNamespaceWorker + class ProjectNamespaceWorker # rubocop:disable Scalability/IdempotentWorker include ClusterCleanupMethods def perform(cluster_id, execution_count = 0) diff --git a/app/workers/clusters/cleanup/service_account_worker.rb b/app/workers/clusters/cleanup/service_account_worker.rb index 95de56d8ebe..a829d68fb20 100644 --- a/app/workers/clusters/cleanup/service_account_worker.rb +++ b/app/workers/clusters/cleanup/service_account_worker.rb @@ -2,7 +2,7 @@ module Clusters module Cleanup - class ServiceAccountWorker + class ServiceAccountWorker # rubocop:disable Scalability/IdempotentWorker include ClusterCleanupMethods def perform(cluster_id) diff --git a/app/workers/concerns/worker_attributes.rb b/app/workers/concerns/worker_attributes.rb index babdb46bb85..55feba673c4 100644 --- a/app/workers/concerns/worker_attributes.rb +++ b/app/workers/concerns/worker_attributes.rb @@ -89,6 +89,14 @@ module WorkerAttributes worker_attributes[:resource_boundary] || :unknown end + def idempotent! + worker_attributes[:idempotent] = true + end + + def idempotent? + worker_attributes[:idempotent] + end + def weight(value) worker_attributes[:weight] = value end diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb index e07a6546e2d..e1544be5aed 100644 --- a/app/workers/container_expiration_policy_worker.rb +++ b/app/workers/container_expiration_policy_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ContainerExpirationPolicyWorker +class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/create_commit_signature_worker.rb b/app/workers/create_commit_signature_worker.rb index 027fea3e402..3da21c56eff 100644 --- a/app/workers/create_commit_signature_worker.rb +++ b/app/workers/create_commit_signature_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CreateCommitSignatureWorker +class CreateCommitSignatureWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/create_evidence_worker.rb b/app/workers/create_evidence_worker.rb index e6fbf59d702..46f211cf3e1 100644 --- a/app/workers/create_evidence_worker.rb +++ b/app/workers/create_evidence_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CreateEvidenceWorker +class CreateEvidenceWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :release_governance diff --git a/app/workers/create_note_diff_file_worker.rb b/app/workers/create_note_diff_file_worker.rb index ca200bd17b4..8a1709f04e1 100644 --- a/app/workers/create_note_diff_file_worker.rb +++ b/app/workers/create_note_diff_file_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CreateNoteDiffFileWorker +class CreateNoteDiffFileWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/create_pipeline_worker.rb b/app/workers/create_pipeline_worker.rb index a75cc643038..ac00fcc5d57 100644 --- a/app/workers/create_pipeline_worker.rb +++ b/app/workers/create_pipeline_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class CreatePipelineWorker +class CreatePipelineWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/delete_container_repository_worker.rb b/app/workers/delete_container_repository_worker.rb index e70b4fb0a58..dbfc273a5ce 100644 --- a/app/workers/delete_container_repository_worker.rb +++ b/app/workers/delete_container_repository_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DeleteContainerRepositoryWorker +class DeleteContainerRepositoryWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExclusiveLeaseGuard diff --git a/app/workers/delete_diff_files_worker.rb b/app/workers/delete_diff_files_worker.rb index e0c1724f1f7..a6759a9d7c4 100644 --- a/app/workers/delete_diff_files_worker.rb +++ b/app/workers/delete_diff_files_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DeleteDiffFilesWorker +class DeleteDiffFilesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/delete_merged_branches_worker.rb b/app/workers/delete_merged_branches_worker.rb index f3d86233c1b..ab3d42e5384 100644 --- a/app/workers/delete_merged_branches_worker.rb +++ b/app/workers/delete_merged_branches_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DeleteMergedBranchesWorker +class DeleteMergedBranchesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/delete_stored_files_worker.rb b/app/workers/delete_stored_files_worker.rb index e1e2f66f573..463f26fdd5a 100644 --- a/app/workers/delete_stored_files_worker.rb +++ b/app/workers/delete_stored_files_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DeleteStoredFilesWorker +class DeleteStoredFilesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category_not_owned! diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb index 0e49e787d8a..d3b87c133d3 100644 --- a/app/workers/delete_user_worker.rb +++ b/app/workers/delete_user_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DeleteUserWorker +class DeleteUserWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :authentication_and_authorization diff --git a/app/workers/deployments/finished_worker.rb b/app/workers/deployments/finished_worker.rb index 6196b032f63..0be420af718 100644 --- a/app/workers/deployments/finished_worker.rb +++ b/app/workers/deployments/finished_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Deployments - class FinishedWorker + class FinishedWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :deployment diff --git a/app/workers/deployments/forward_deployment_worker.rb b/app/workers/deployments/forward_deployment_worker.rb index a25b8ca0478..a6f246dbbbd 100644 --- a/app/workers/deployments/forward_deployment_worker.rb +++ b/app/workers/deployments/forward_deployment_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Deployments - class ForwardDeploymentWorker + class ForwardDeploymentWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :deployment diff --git a/app/workers/deployments/success_worker.rb b/app/workers/deployments/success_worker.rb index 4a29f1aef52..17f790d2f6f 100644 --- a/app/workers/deployments/success_worker.rb +++ b/app/workers/deployments/success_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Deployments - class SuccessWorker + class SuccessWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :deployment diff --git a/app/workers/detect_repository_languages_worker.rb b/app/workers/detect_repository_languages_worker.rb index 954d0f9336b..ef66287a692 100644 --- a/app/workers/detect_repository_languages_worker.rb +++ b/app/workers/detect_repository_languages_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class DetectRepositoryLanguagesWorker +class DetectRepositoryLanguagesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace include ExclusiveLeaseGuard diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb index c2b1e642604..37398b18aef 100644 --- a/app/workers/email_receiver_worker.rb +++ b/app/workers/email_receiver_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class EmailReceiverWorker +class EmailReceiverWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :issue_tracking diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb index be66e2b1188..2c546bc3c20 100644 --- a/app/workers/emails_on_push_worker.rb +++ b/app/workers/emails_on_push_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class EmailsOnPushWorker +class EmailsOnPushWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker attr_reader :email, :skip_premailer diff --git a/app/workers/environments/auto_stop_cron_worker.rb b/app/workers/environments/auto_stop_cron_worker.rb index fdc9490453c..de5e10a0976 100644 --- a/app/workers/environments/auto_stop_cron_worker.rb +++ b/app/workers/environments/auto_stop_cron_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Environments - class AutoStopCronWorker + class AutoStopCronWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/error_tracking_issue_link_worker.rb b/app/workers/error_tracking_issue_link_worker.rb index b306ecc154b..d59abaf8683 100644 --- a/app/workers/error_tracking_issue_link_worker.rb +++ b/app/workers/error_tracking_issue_link_worker.rb @@ -5,7 +5,7 @@ # If a link to a different GitLab issue exists, a new link # will still be created, but will not be visible in Sentry # until the prior link is deleted. -class ErrorTrackingIssueLinkWorker +class ErrorTrackingIssueLinkWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExclusiveLeaseGuard include Gitlab::Utils::StrongMemoize diff --git a/app/workers/expire_build_artifacts_worker.rb b/app/workers/expire_build_artifacts_worker.rb index 07f516a3390..12372961250 100644 --- a/app/workers/expire_build_artifacts_worker.rb +++ b/app/workers/expire_build_artifacts_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ExpireBuildArtifactsWorker +class ExpireBuildArtifactsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb index db5240d5c8e..48fd086f88f 100644 --- a/app/workers/expire_build_instance_artifacts_worker.rb +++ b/app/workers/expire_build_instance_artifacts_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ExpireBuildInstanceArtifactsWorker +class ExpireBuildInstanceArtifactsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :continuous_integration diff --git a/app/workers/expire_job_cache_worker.rb b/app/workers/expire_job_cache_worker.rb index 0363429587e..1cd5fa5d1c5 100644 --- a/app/workers/expire_job_cache_worker.rb +++ b/app/workers/expire_job_cache_worker.rb @@ -6,6 +6,7 @@ class ExpireJobCacheWorker queue_namespace :pipeline_cache latency_sensitive_worker! + idempotent! # rubocop: disable CodeReuse/ActiveRecord def perform(job_id) diff --git a/app/workers/expire_pipeline_cache_worker.rb b/app/workers/expire_pipeline_cache_worker.rb index 1d204e0a19e..d92141c70cc 100644 --- a/app/workers/expire_pipeline_cache_worker.rb +++ b/app/workers/expire_pipeline_cache_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ExpirePipelineCacheWorker +class ExpirePipelineCacheWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/file_hook_worker.rb b/app/workers/file_hook_worker.rb index 24fc2d75d24..f8cdea54a17 100644 --- a/app/workers/file_hook_worker.rb +++ b/app/workers/file_hook_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class FileHookWorker +class FileHookWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker sidekiq_options retry: false diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb index ad119917774..37ca3af517f 100644 --- a/app/workers/git_garbage_collect_worker.rb +++ b/app/workers/git_garbage_collect_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GitGarbageCollectWorker +class GitGarbageCollectWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker sidekiq_options retry: false diff --git a/app/workers/gitlab/github_import/advance_stage_worker.rb b/app/workers/gitlab/github_import/advance_stage_worker.rb index 44e69e48694..8c379be2ae4 100644 --- a/app/workers/gitlab/github_import/advance_stage_worker.rb +++ b/app/workers/gitlab/github_import/advance_stage_worker.rb @@ -6,7 +6,7 @@ module Gitlab # number of jobs to complete, without blocking a thread. Once all jobs have # been completed this worker will advance the import process to the next # stage. - class AdvanceStageWorker + class AdvanceStageWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker sidekiq_options dead: false diff --git a/app/workers/gitlab/github_import/import_diff_note_worker.rb b/app/workers/gitlab/github_import/import_diff_note_worker.rb index ef2a74c51c5..25fb0375692 100644 --- a/app/workers/gitlab/github_import/import_diff_note_worker.rb +++ b/app/workers/gitlab/github_import/import_diff_note_worker.rb @@ -2,7 +2,7 @@ module Gitlab module GithubImport - class ImportDiffNoteWorker + class ImportDiffNoteWorker # rubocop:disable Scalability/IdempotentWorker include ObjectImporter def representation_class diff --git a/app/workers/gitlab/github_import/import_issue_worker.rb b/app/workers/gitlab/github_import/import_issue_worker.rb index 1b081ae5966..d9c496e3eb3 100644 --- a/app/workers/gitlab/github_import/import_issue_worker.rb +++ b/app/workers/gitlab/github_import/import_issue_worker.rb @@ -2,7 +2,7 @@ module Gitlab module GithubImport - class ImportIssueWorker + class ImportIssueWorker # rubocop:disable Scalability/IdempotentWorker include ObjectImporter def representation_class diff --git a/app/workers/gitlab/github_import/import_lfs_object_worker.rb b/app/workers/gitlab/github_import/import_lfs_object_worker.rb index 520c5cb091a..78f78fdb160 100644 --- a/app/workers/gitlab/github_import/import_lfs_object_worker.rb +++ b/app/workers/gitlab/github_import/import_lfs_object_worker.rb @@ -2,7 +2,7 @@ module Gitlab module GithubImport - class ImportLfsObjectWorker + class ImportLfsObjectWorker # rubocop:disable Scalability/IdempotentWorker include ObjectImporter def representation_class diff --git a/app/workers/gitlab/github_import/import_note_worker.rb b/app/workers/gitlab/github_import/import_note_worker.rb index d2b4c36a5b9..d0f97a15afd 100644 --- a/app/workers/gitlab/github_import/import_note_worker.rb +++ b/app/workers/gitlab/github_import/import_note_worker.rb @@ -2,7 +2,7 @@ module Gitlab module GithubImport - class ImportNoteWorker + class ImportNoteWorker # rubocop:disable Scalability/IdempotentWorker include ObjectImporter def representation_class diff --git a/app/workers/gitlab/github_import/import_pull_request_worker.rb b/app/workers/gitlab/github_import/import_pull_request_worker.rb index 62a6da152a3..ec806ad170b 100644 --- a/app/workers/gitlab/github_import/import_pull_request_worker.rb +++ b/app/workers/gitlab/github_import/import_pull_request_worker.rb @@ -2,7 +2,7 @@ module Gitlab module GithubImport - class ImportPullRequestWorker + class ImportPullRequestWorker # rubocop:disable Scalability/IdempotentWorker include ObjectImporter def representation_class diff --git a/app/workers/gitlab/github_import/refresh_import_jid_worker.rb b/app/workers/gitlab/github_import/refresh_import_jid_worker.rb index 76723e4a61f..0ddd893d0d1 100644 --- a/app/workers/gitlab/github_import/refresh_import_jid_worker.rb +++ b/app/workers/gitlab/github_import/refresh_import_jid_worker.rb @@ -2,7 +2,7 @@ module Gitlab module GithubImport - class RefreshImportJidWorker + class RefreshImportJidWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue diff --git a/app/workers/gitlab/github_import/stage/finish_import_worker.rb b/app/workers/gitlab/github_import/stage/finish_import_worker.rb index ee64f62637e..73699a74a4a 100644 --- a/app/workers/gitlab/github_import/stage/finish_import_worker.rb +++ b/app/workers/gitlab/github_import/stage/finish_import_worker.rb @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class FinishImportWorker + class FinishImportWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods diff --git a/app/workers/gitlab/github_import/stage/import_base_data_worker.rb b/app/workers/gitlab/github_import/stage/import_base_data_worker.rb index ccfed2ae187..11c2a2ac9b4 100644 --- a/app/workers/gitlab/github_import/stage/import_base_data_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_base_data_worker.rb @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class ImportBaseDataWorker + class ImportBaseDataWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods diff --git a/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb b/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb index 7007754ff2e..68b6e159fa4 100644 --- a/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_issues_and_diff_notes_worker.rb @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class ImportIssuesAndDiffNotesWorker + class ImportIssuesAndDiffNotesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods diff --git a/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb b/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb index 29257603a9d..a19df399969 100644 --- a/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_lfs_objects_worker.rb @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class ImportLfsObjectsWorker + class ImportLfsObjectsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods diff --git a/app/workers/gitlab/github_import/stage/import_notes_worker.rb b/app/workers/gitlab/github_import/stage/import_notes_worker.rb index ccf0013180d..49b9821cd45 100644 --- a/app/workers/gitlab/github_import/stage/import_notes_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_notes_worker.rb @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class ImportNotesWorker + class ImportNotesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods 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 37a7a7f4ba0..3299db5653b 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 @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class ImportPullRequestsWorker + class ImportPullRequestsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods 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 b5e30470070..cb9ef1cd198 100644 --- a/app/workers/gitlab/github_import/stage/import_repository_worker.rb +++ b/app/workers/gitlab/github_import/stage/import_repository_worker.rb @@ -3,7 +3,7 @@ module Gitlab module GithubImport module Stage - class ImportRepositoryWorker + class ImportRepositoryWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include GithubImport::Queue include StageMethods diff --git a/app/workers/gitlab/phabricator_import/base_worker.rb b/app/workers/gitlab/phabricator_import/base_worker.rb index faae71d4627..82ef9e825f9 100644 --- a/app/workers/gitlab/phabricator_import/base_worker.rb +++ b/app/workers/gitlab/phabricator_import/base_worker.rb @@ -18,7 +18,7 @@ # - It marks the import as finished when all remaining jobs are done module Gitlab module PhabricatorImport - class BaseWorker + class BaseWorker # rubocop:disable Scalability/IdempotentWorker include WorkerAttributes include Gitlab::ExclusiveLeaseHelpers diff --git a/app/workers/gitlab/phabricator_import/import_tasks_worker.rb b/app/workers/gitlab/phabricator_import/import_tasks_worker.rb index b5d9e80797b..1b1d7b35dd5 100644 --- a/app/workers/gitlab/phabricator_import/import_tasks_worker.rb +++ b/app/workers/gitlab/phabricator_import/import_tasks_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Gitlab module PhabricatorImport - class ImportTasksWorker < BaseWorker + class ImportTasksWorker < BaseWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ProjectImportOptions # This marks the project as failed after too many tries diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb index bd2225e6d7c..f9b5a7d99ed 100644 --- a/app/workers/gitlab_shell_worker.rb +++ b/app/workers/gitlab_shell_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GitlabShellWorker +class GitlabShellWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include Gitlab::ShellAdapter diff --git a/app/workers/gitlab_usage_ping_worker.rb b/app/workers/gitlab_usage_ping_worker.rb index 002542e26f4..9f0cf1728dd 100644 --- a/app/workers/gitlab_usage_ping_worker.rb +++ b/app/workers/gitlab_usage_ping_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GitlabUsagePingWorker +class GitlabUsagePingWorker # rubocop:disable Scalability/IdempotentWorker LEASE_TIMEOUT = 86400 include ApplicationWorker diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb index fc751f8b612..d80a2dad7d9 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 +class GroupDestroyWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace diff --git a/app/workers/group_export_worker.rb b/app/workers/group_export_worker.rb index a2d34e8c8bf..3e0390429d6 100644 --- a/app/workers/group_export_worker.rb +++ b/app/workers/group_export_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GroupExportWorker +class GroupExportWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace diff --git a/app/workers/group_import_worker.rb b/app/workers/group_import_worker.rb index f283eab5814..b6fc5afc28c 100644 --- a/app/workers/group_import_worker.rb +++ b/app/workers/group_import_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class GroupImportWorker +class GroupImportWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace diff --git a/app/workers/hashed_storage/base_worker.rb b/app/workers/hashed_storage/base_worker.rb index 1ab2108f6bb..372440996d9 100644 --- a/app/workers/hashed_storage/base_worker.rb +++ b/app/workers/hashed_storage/base_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module HashedStorage - class BaseWorker + class BaseWorker # rubocop:disable Scalability/IdempotentWorker include ExclusiveLeaseGuard include WorkerAttributes diff --git a/app/workers/hashed_storage/migrator_worker.rb b/app/workers/hashed_storage/migrator_worker.rb index 72a3faec5f4..5cbdfcb0602 100644 --- a/app/workers/hashed_storage/migrator_worker.rb +++ b/app/workers/hashed_storage/migrator_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module HashedStorage - class MigratorWorker + class MigratorWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :hashed_storage diff --git a/app/workers/hashed_storage/project_migrate_worker.rb b/app/workers/hashed_storage/project_migrate_worker.rb index 0174467923d..3ce60ce7eb6 100644 --- a/app/workers/hashed_storage/project_migrate_worker.rb +++ b/app/workers/hashed_storage/project_migrate_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module HashedStorage - class ProjectMigrateWorker < BaseWorker + class ProjectMigrateWorker < BaseWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :hashed_storage diff --git a/app/workers/hashed_storage/project_rollback_worker.rb b/app/workers/hashed_storage/project_rollback_worker.rb index 55e1d7ab23e..17b3cca83e1 100644 --- a/app/workers/hashed_storage/project_rollback_worker.rb +++ b/app/workers/hashed_storage/project_rollback_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module HashedStorage - class ProjectRollbackWorker < BaseWorker + class ProjectRollbackWorker < BaseWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :hashed_storage diff --git a/app/workers/hashed_storage/rollbacker_worker.rb b/app/workers/hashed_storage/rollbacker_worker.rb index 8babdcfb96d..a220d3b2226 100644 --- a/app/workers/hashed_storage/rollbacker_worker.rb +++ b/app/workers/hashed_storage/rollbacker_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module HashedStorage - class RollbackerWorker + class RollbackerWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :hashed_storage diff --git a/app/workers/import_export_project_cleanup_worker.rb b/app/workers/import_export_project_cleanup_worker.rb index ae236fa1fcd..dd345434d08 100644 --- a/app/workers/import_export_project_cleanup_worker.rb +++ b/app/workers/import_export_project_cleanup_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ImportExportProjectCleanupWorker +class ImportExportProjectCleanupWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/import_issues_csv_worker.rb b/app/workers/import_issues_csv_worker.rb index 7c5584146ca..c7b5f8cd0a7 100644 --- a/app/workers/import_issues_csv_worker.rb +++ b/app/workers/import_issues_csv_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ImportIssuesCsvWorker +class ImportIssuesCsvWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :issue_tracking diff --git a/app/workers/incident_management/process_alert_worker.rb b/app/workers/incident_management/process_alert_worker.rb index f3d5bc5c66b..8d4294cc231 100644 --- a/app/workers/incident_management/process_alert_worker.rb +++ b/app/workers/incident_management/process_alert_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module IncidentManagement - class ProcessAlertWorker + class ProcessAlertWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :incident_management diff --git a/app/workers/invalid_gpg_signature_update_worker.rb b/app/workers/invalid_gpg_signature_update_worker.rb index e1c2eefbf0f..1fd959c8763 100644 --- a/app/workers/invalid_gpg_signature_update_worker.rb +++ b/app/workers/invalid_gpg_signature_update_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class InvalidGpgSignatureUpdateWorker +class InvalidGpgSignatureUpdateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb index a133ed6ed1b..91ab0d69ad1 100644 --- a/app/workers/irker_worker.rb +++ b/app/workers/irker_worker.rb @@ -3,7 +3,7 @@ require 'json' require 'socket' -class IrkerWorker +class IrkerWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :integrations diff --git a/app/workers/issue_due_scheduler_worker.rb b/app/workers/issue_due_scheduler_worker.rb index 59027907284..d735295d046 100644 --- a/app/workers/issue_due_scheduler_worker.rb +++ b/app/workers/issue_due_scheduler_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class IssueDueSchedulerWorker +class IssueDueSchedulerWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/mail_scheduler/issue_due_worker.rb b/app/workers/mail_scheduler/issue_due_worker.rb index 6df816de71f..309d3e13477 100644 --- a/app/workers/mail_scheduler/issue_due_worker.rb +++ b/app/workers/mail_scheduler/issue_due_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module MailScheduler - class IssueDueWorker + class IssueDueWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include MailSchedulerQueue diff --git a/app/workers/mail_scheduler/notification_service_worker.rb b/app/workers/mail_scheduler/notification_service_worker.rb index ec659e39b24..691af2a724d 100644 --- a/app/workers/mail_scheduler/notification_service_worker.rb +++ b/app/workers/mail_scheduler/notification_service_worker.rb @@ -3,7 +3,7 @@ require 'active_job/arguments' module MailScheduler - class NotificationServiceWorker + class NotificationServiceWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include MailSchedulerQueue diff --git a/app/workers/merge_request_mergeability_check_worker.rb b/app/workers/merge_request_mergeability_check_worker.rb index ed35284b66c..a26c1a886f6 100644 --- a/app/workers/merge_request_mergeability_check_worker.rb +++ b/app/workers/merge_request_mergeability_check_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class MergeRequestMergeabilityCheckWorker +class MergeRequestMergeabilityCheckWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb index 48bc205113f..a7b926e143f 100644 --- a/app/workers/merge_worker.rb +++ b/app/workers/merge_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class MergeWorker +class MergeWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/migrate_external_diffs_worker.rb b/app/workers/migrate_external_diffs_worker.rb index d248e2b5500..0a95f40aa8f 100644 --- a/app/workers/migrate_external_diffs_worker.rb +++ b/app/workers/migrate_external_diffs_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class MigrateExternalDiffsWorker +class MigrateExternalDiffsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb index 113afc268f2..1c8054d8fbd 100644 --- a/app/workers/namespaceless_project_destroy_worker.rb +++ b/app/workers/namespaceless_project_destroy_worker.rb @@ -6,7 +6,7 @@ # used to belong to. Projects in this state should be rare. # The worker will reject doing anything for projects that *do* have a # namespace. For those use ProjectDestroyWorker instead. -class NamespacelessProjectDestroyWorker +class NamespacelessProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace diff --git a/app/workers/namespaces/prune_aggregation_schedules_worker.rb b/app/workers/namespaces/prune_aggregation_schedules_worker.rb index aeb5aa37a10..b94c8b7b4ba 100644 --- a/app/workers/namespaces/prune_aggregation_schedules_worker.rb +++ b/app/workers/namespaces/prune_aggregation_schedules_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Namespaces - class PruneAggregationSchedulesWorker + class PruneAggregationSchedulesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/namespaces/root_statistics_worker.rb b/app/workers/namespaces/root_statistics_worker.rb index fd772c8cff6..5fceeb8e03d 100644 --- a/app/workers/namespaces/root_statistics_worker.rb +++ b/app/workers/namespaces/root_statistics_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Namespaces - class RootStatisticsWorker + class RootStatisticsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :update_namespace_statistics diff --git a/app/workers/namespaces/schedule_aggregation_worker.rb b/app/workers/namespaces/schedule_aggregation_worker.rb index 87e135fbf21..60210e2f5a7 100644 --- a/app/workers/namespaces/schedule_aggregation_worker.rb +++ b/app/workers/namespaces/schedule_aggregation_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Namespaces - class ScheduleAggregationWorker + class ScheduleAggregationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :update_namespace_statistics diff --git a/app/workers/new_issue_worker.rb b/app/workers/new_issue_worker.rb index d696165b447..ded5104c708 100644 --- a/app/workers/new_issue_worker.rb +++ b/app/workers/new_issue_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class NewIssueWorker +class NewIssueWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include NewIssuable diff --git a/app/workers/new_merge_request_worker.rb b/app/workers/new_merge_request_worker.rb index e31ddae1f13..3b101435f7a 100644 --- a/app/workers/new_merge_request_worker.rb +++ b/app/workers/new_merge_request_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class NewMergeRequestWorker +class NewMergeRequestWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include NewIssuable diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb index b446e376007..af1cef432eb 100644 --- a/app/workers/new_note_worker.rb +++ b/app/workers/new_note_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class NewNoteWorker +class NewNoteWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :issue_tracking diff --git a/app/workers/new_release_worker.rb b/app/workers/new_release_worker.rb index edfdb2d7aff..3c19e5f3d2b 100644 --- a/app/workers/new_release_worker.rb +++ b/app/workers/new_release_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class NewReleaseWorker +class NewReleaseWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker queue_namespace :notifications diff --git a/app/workers/object_pool/create_worker.rb b/app/workers/object_pool/create_worker.rb index 135b99886dc..cf87ad95077 100644 --- a/app/workers/object_pool/create_worker.rb +++ b/app/workers/object_pool/create_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ObjectPool - class CreateWorker + class CreateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ObjectPoolQueue include ExclusiveLeaseGuard diff --git a/app/workers/object_pool/destroy_worker.rb b/app/workers/object_pool/destroy_worker.rb index ca00d467d9b..d42cee59d03 100644 --- a/app/workers/object_pool/destroy_worker.rb +++ b/app/workers/object_pool/destroy_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ObjectPool - class DestroyWorker + class DestroyWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ObjectPoolQueue diff --git a/app/workers/object_pool/join_worker.rb b/app/workers/object_pool/join_worker.rb index ddd002eabb8..f1008d3be83 100644 --- a/app/workers/object_pool/join_worker.rb +++ b/app/workers/object_pool/join_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ObjectPool - class JoinWorker + class JoinWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ObjectPoolQueue diff --git a/app/workers/object_pool/schedule_join_worker.rb b/app/workers/object_pool/schedule_join_worker.rb index 647a8b72435..c00bb2967f2 100644 --- a/app/workers/object_pool/schedule_join_worker.rb +++ b/app/workers/object_pool/schedule_join_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ObjectPool - class ScheduleJoinWorker + class ScheduleJoinWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ObjectPoolQueue diff --git a/app/workers/object_storage/background_move_worker.rb b/app/workers/object_storage/background_move_worker.rb index 55f8e1c3ede..7b0a7c7ec58 100644 --- a/app/workers/object_storage/background_move_worker.rb +++ b/app/workers/object_storage/background_move_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module ObjectStorage - class BackgroundMoveWorker + class BackgroundMoveWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ObjectStorageQueue diff --git a/app/workers/object_storage/migrate_uploads_worker.rb b/app/workers/object_storage/migrate_uploads_worker.rb index 01e6fdb2d3e..d9d21f2cb7e 100644 --- a/app/workers/object_storage/migrate_uploads_worker.rb +++ b/app/workers/object_storage/migrate_uploads_worker.rb @@ -1,5 +1,6 @@ # frozen_string_literal: true +# rubocop:disable Scalability/IdempotentWorker module ObjectStorage class MigrateUploadsWorker include ApplicationWorker @@ -137,3 +138,4 @@ module ObjectStorage end end end +# rubocop:enable Scalability/IdempotentWorker diff --git a/app/workers/pages_domain_removal_cron_worker.rb b/app/workers/pages_domain_removal_cron_worker.rb index 1c96dd6ad8c..cb24441d2f7 100644 --- a/app/workers/pages_domain_removal_cron_worker.rb +++ b/app/workers/pages_domain_removal_cron_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PagesDomainRemovalCronWorker +class PagesDomainRemovalCronWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/pages_domain_ssl_renewal_cron_worker.rb b/app/workers/pages_domain_ssl_renewal_cron_worker.rb index c1201b935d1..fe6d516d3cf 100644 --- a/app/workers/pages_domain_ssl_renewal_cron_worker.rb +++ b/app/workers/pages_domain_ssl_renewal_cron_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PagesDomainSslRenewalCronWorker +class PagesDomainSslRenewalCronWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/pages_domain_ssl_renewal_worker.rb b/app/workers/pages_domain_ssl_renewal_worker.rb index 4db7d22ef7e..561fd59d471 100644 --- a/app/workers/pages_domain_ssl_renewal_worker.rb +++ b/app/workers/pages_domain_ssl_renewal_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PagesDomainSslRenewalWorker +class PagesDomainSslRenewalWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :pages diff --git a/app/workers/pages_domain_verification_cron_worker.rb b/app/workers/pages_domain_verification_cron_worker.rb index b06aa65a8e5..a30f0b981d8 100644 --- a/app/workers/pages_domain_verification_cron_worker.rb +++ b/app/workers/pages_domain_verification_cron_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PagesDomainVerificationCronWorker +class PagesDomainVerificationCronWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/pages_domain_verification_worker.rb b/app/workers/pages_domain_verification_worker.rb index b0888036498..1b4d9d3994c 100644 --- a/app/workers/pages_domain_verification_worker.rb +++ b/app/workers/pages_domain_verification_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PagesDomainVerificationWorker +class PagesDomainVerificationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :pages diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb index 484d9053849..875f17282f9 100644 --- a/app/workers/pages_worker.rb +++ b/app/workers/pages_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PagesWorker +class PagesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker sidekiq_options retry: 3 diff --git a/app/workers/personal_access_tokens/expiring_worker.rb b/app/workers/personal_access_tokens/expiring_worker.rb index 84f7ce9d5d7..86240f827fc 100644 --- a/app/workers/personal_access_tokens/expiring_worker.rb +++ b/app/workers/personal_access_tokens/expiring_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module PersonalAccessTokens - class ExpiringWorker + class ExpiringWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/pipeline_hooks_worker.rb b/app/workers/pipeline_hooks_worker.rb index 04abc9c88fd..3fa0c5ab9af 100644 --- a/app/workers/pipeline_hooks_worker.rb +++ b/app/workers/pipeline_hooks_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineHooksWorker +class PipelineHooksWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/pipeline_metrics_worker.rb b/app/workers/pipeline_metrics_worker.rb index 3830522aaa1..65a5a94ed8a 100644 --- a/app/workers/pipeline_metrics_worker.rb +++ b/app/workers/pipeline_metrics_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineMetricsWorker +class PipelineMetricsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/pipeline_notification_worker.rb b/app/workers/pipeline_notification_worker.rb index 62ecbc8a047..e9081cc416f 100644 --- a/app/workers/pipeline_notification_worker.rb +++ b/app/workers/pipeline_notification_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineNotificationWorker +class PipelineNotificationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb index 200f3619332..2f8ab0d6202 100644 --- a/app/workers/pipeline_process_worker.rb +++ b/app/workers/pipeline_process_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineProcessWorker +class PipelineProcessWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/pipeline_schedule_worker.rb b/app/workers/pipeline_schedule_worker.rb index 8b326b9dbb6..d81b978f9b0 100644 --- a/app/workers/pipeline_schedule_worker.rb +++ b/app/workers/pipeline_schedule_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineScheduleWorker +class PipelineScheduleWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/pipeline_success_worker.rb b/app/workers/pipeline_success_worker.rb index 5c24f00e0c3..3b4ab461ae7 100644 --- a/app/workers/pipeline_success_worker.rb +++ b/app/workers/pipeline_success_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineSuccessWorker +class PipelineSuccessWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/pipeline_update_worker.rb b/app/workers/pipeline_update_worker.rb index 0321ea5a6ce..b170781202a 100644 --- a/app/workers/pipeline_update_worker.rb +++ b/app/workers/pipeline_update_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PipelineUpdateWorker +class PipelineUpdateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb index d5038f1152b..f0fd3c9a808 100644 --- a/app/workers/post_receive.rb +++ b/app/workers/post_receive.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PostReceive +class PostReceive # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb index ca2896946c9..d604ac12e8a 100644 --- a/app/workers/process_commit_worker.rb +++ b/app/workers/process_commit_worker.rb @@ -7,7 +7,7 @@ # result of this the workload of this worker should be kept to a bare minimum. # Consider using an extra worker if you need to add any extra (and potentially # slow) processing of commits. -class ProcessCommitWorker +class ProcessCommitWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb index ae1d57aa124..fc79a988c8b 100644 --- a/app/workers/project_cache_worker.rb +++ b/app/workers/project_cache_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Worker for updating any project specific caches. -class ProjectCacheWorker +class ProjectCacheWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker latency_sensitive_worker! diff --git a/app/workers/project_daily_statistics_worker.rb b/app/workers/project_daily_statistics_worker.rb index 19c2fd67763..c60bee0ffdc 100644 --- a/app/workers/project_daily_statistics_worker.rb +++ b/app/workers/project_daily_statistics_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ProjectDailyStatisticsWorker +class ProjectDailyStatisticsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb index 1d20837faa2..b3e7996f4a4 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 +class ProjectDestroyWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb index 4d2cc3cd32d..eefba6d25c7 100644 --- a/app/workers/project_export_worker.rb +++ b/app/workers/project_export_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ProjectExportWorker +class ProjectExportWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb index 38a2a7414a5..84c3a3e52d0 100644 --- a/app/workers/project_service_worker.rb +++ b/app/workers/project_service_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ProjectServiceWorker +class ProjectServiceWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker sidekiq_options dead: false diff --git a/app/workers/propagate_service_template_worker.rb b/app/workers/propagate_service_template_worker.rb index 73a2b453207..f3a6bda1821 100644 --- a/app/workers/propagate_service_template_worker.rb +++ b/app/workers/propagate_service_template_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Worker for updating any project specific caches. -class PropagateServiceTemplateWorker +class PropagateServiceTemplateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb index 541a17c0fcf..330de4c7cba 100644 --- a/app/workers/prune_old_events_worker.rb +++ b/app/workers/prune_old_events_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class PruneOldEventsWorker +class PruneOldEventsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/prune_web_hook_logs_worker.rb b/app/workers/prune_web_hook_logs_worker.rb index dd4f16a69da..a8e81a24ecd 100644 --- a/app/workers/prune_web_hook_logs_worker.rb +++ b/app/workers/prune_web_hook_logs_worker.rb @@ -2,7 +2,7 @@ # Worker that deletes a fixed number of outdated rows from the "web_hook_logs" # table. -class PruneWebHookLogsWorker +class PruneWebHookLogsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/reactive_caching_worker.rb b/app/workers/reactive_caching_worker.rb index 6f82ad83137..bcaeaec5709 100644 --- a/app/workers/reactive_caching_worker.rb +++ b/app/workers/reactive_caching_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ReactiveCachingWorker +class ReactiveCachingWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category_not_owned! diff --git a/app/workers/rebase_worker.rb b/app/workers/rebase_worker.rb index ddf5c31a1c2..2e13af5e0aa 100644 --- a/app/workers/rebase_worker.rb +++ b/app/workers/rebase_worker.rb @@ -2,7 +2,7 @@ # The RebaseWorker must be wrapped in important concurrency code, so should only # be scheduled via MergeRequest#rebase_async -class RebaseWorker +class RebaseWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/remote_mirror_notification_worker.rb b/app/workers/remote_mirror_notification_worker.rb index 706131d4e4b..33f5002014d 100644 --- a/app/workers/remote_mirror_notification_worker.rb +++ b/app/workers/remote_mirror_notification_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RemoteMirrorNotificationWorker +class RemoteMirrorNotificationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb index db35dfb3ca8..8226f22837c 100644 --- a/app/workers/remove_expired_group_links_worker.rb +++ b/app/workers/remove_expired_group_links_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RemoveExpiredGroupLinksWorker +class RemoveExpiredGroupLinksWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/remove_expired_members_worker.rb b/app/workers/remove_expired_members_worker.rb index 278adee98e9..f56a6cd9fa2 100644 --- a/app/workers/remove_expired_members_worker.rb +++ b/app/workers/remove_expired_members_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RemoveExpiredMembersWorker +class RemoveExpiredMembersWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/remove_unreferenced_lfs_objects_worker.rb b/app/workers/remove_unreferenced_lfs_objects_worker.rb index 5e3998f3915..76ab23ebbd5 100644 --- a/app/workers/remove_unreferenced_lfs_objects_worker.rb +++ b/app/workers/remove_unreferenced_lfs_objects_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RemoveUnreferencedLfsObjectsWorker +class RemoveUnreferencedLfsObjectsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/repository_archive_cache_worker.rb b/app/workers/repository_archive_cache_worker.rb index 76e08a80c15..84f61a60953 100644 --- a/app/workers/repository_archive_cache_worker.rb +++ b/app/workers/repository_archive_cache_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RepositoryArchiveCacheWorker +class RepositoryArchiveCacheWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/repository_check/batch_worker.rb b/app/workers/repository_check/batch_worker.rb index 4091c30f498..3e5e6a25228 100644 --- a/app/workers/repository_check/batch_worker.rb +++ b/app/workers/repository_check/batch_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RepositoryCheck - class BatchWorker + class BatchWorker # rubocop:disable Scalability/IdempotentWorker prepend_if_ee('::EE::RepositoryCheck::BatchWorker') # rubocop: disable Cop/InjectEnterpriseEditionModule include ApplicationWorker diff --git a/app/workers/repository_check/clear_worker.rb b/app/workers/repository_check/clear_worker.rb index 01964c69fb2..1689b9bf251 100644 --- a/app/workers/repository_check/clear_worker.rb +++ b/app/workers/repository_check/clear_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RepositoryCheck - class ClearWorker + class ClearWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include RepositoryCheckQueue diff --git a/app/workers/repository_check/dispatch_worker.rb b/app/workers/repository_check/dispatch_worker.rb index f68be8832eb..d7a145011fa 100644 --- a/app/workers/repository_check/dispatch_worker.rb +++ b/app/workers/repository_check/dispatch_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RepositoryCheck - class DispatchWorker + class DispatchWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/repository_check/single_repository_worker.rb b/app/workers/repository_check/single_repository_worker.rb index cadb1de356c..b25a20b3eff 100644 --- a/app/workers/repository_check/single_repository_worker.rb +++ b/app/workers/repository_check/single_repository_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module RepositoryCheck - class SingleRepositoryWorker + class SingleRepositoryWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include RepositoryCheckQueue diff --git a/app/workers/repository_cleanup_worker.rb b/app/workers/repository_cleanup_worker.rb index dd2cbd42d1f..33b7223dd95 100644 --- a/app/workers/repository_cleanup_worker.rb +++ b/app/workers/repository_cleanup_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RepositoryCleanupWorker +class RepositoryCleanupWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker sidekiq_options retry: 3 diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb index ba141f808a7..4b90239dcb8 100644 --- a/app/workers/repository_fork_worker.rb +++ b/app/workers/repository_fork_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RepositoryForkWorker +class RepositoryForkWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include Gitlab::ShellAdapter include ProjectStartImport diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb index 15677fb0a95..9f17ef467e3 100644 --- a/app/workers/repository_import_worker.rb +++ b/app/workers/repository_import_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RepositoryImportWorker +class RepositoryImportWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExceptionBacktrace include ProjectStartImport diff --git a/app/workers/repository_remove_remote_worker.rb b/app/workers/repository_remove_remote_worker.rb index 3e55ebc77ed..23a9ec1e202 100644 --- a/app/workers/repository_remove_remote_worker.rb +++ b/app/workers/repository_remove_remote_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RepositoryRemoveRemoteWorker +class RepositoryRemoveRemoteWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExclusiveLeaseGuard diff --git a/app/workers/repository_update_remote_mirror_worker.rb b/app/workers/repository_update_remote_mirror_worker.rb index d1dec4cb732..cfff2382f04 100644 --- a/app/workers/repository_update_remote_mirror_worker.rb +++ b/app/workers/repository_update_remote_mirror_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RepositoryUpdateRemoteMirrorWorker +class RepositoryUpdateRemoteMirrorWorker # rubocop:disable Scalability/IdempotentWorker UpdateError = Class.new(StandardError) include ApplicationWorker diff --git a/app/workers/requests_profiles_worker.rb b/app/workers/requests_profiles_worker.rb index b711cb99082..106f04d9409 100644 --- a/app/workers/requests_profiles_worker.rb +++ b/app/workers/requests_profiles_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RequestsProfilesWorker +class RequestsProfilesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/run_pipeline_schedule_worker.rb b/app/workers/run_pipeline_schedule_worker.rb index f8f8a2fe7ae..7d76cbed77f 100644 --- a/app/workers/run_pipeline_schedule_worker.rb +++ b/app/workers/run_pipeline_schedule_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class RunPipelineScheduleWorker +class RunPipelineScheduleWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/schedule_migrate_external_diffs_worker.rb b/app/workers/schedule_migrate_external_diffs_worker.rb index 0e3c62cf282..4e7b60c4ab7 100644 --- a/app/workers/schedule_migrate_external_diffs_worker.rb +++ b/app/workers/schedule_migrate_external_diffs_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class ScheduleMigrateExternalDiffsWorker +class ScheduleMigrateExternalDiffsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext: # This schedules the `MigrateExternalDiffsWorker` diff --git a/app/workers/self_monitoring_project_create_worker.rb b/app/workers/self_monitoring_project_create_worker.rb index 429ac8aacc4..8177efb1683 100644 --- a/app/workers/self_monitoring_project_create_worker.rb +++ b/app/workers/self_monitoring_project_create_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class SelfMonitoringProjectCreateWorker +class SelfMonitoringProjectCreateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExclusiveLeaseGuard include SelfMonitoringProjectWorker diff --git a/app/workers/self_monitoring_project_delete_worker.rb b/app/workers/self_monitoring_project_delete_worker.rb index 07a7d3f6c45..4fa05d71de5 100644 --- a/app/workers/self_monitoring_project_delete_worker.rb +++ b/app/workers/self_monitoring_project_delete_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class SelfMonitoringProjectDeleteWorker +class SelfMonitoringProjectDeleteWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ExclusiveLeaseGuard include SelfMonitoringProjectWorker diff --git a/app/workers/stage_update_worker.rb b/app/workers/stage_update_worker.rb index a96c4c6dda2..a5097d61927 100644 --- a/app/workers/stage_update_worker.rb +++ b/app/workers/stage_update_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class StageUpdateWorker +class StageUpdateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb index 6e4ffa36854..b3b1ed66efc 100644 --- a/app/workers/stuck_ci_jobs_worker.rb +++ b/app/workers/stuck_ci_jobs_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class StuckCiJobsWorker +class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue diff --git a/app/workers/stuck_import_jobs_worker.rb b/app/workers/stuck_import_jobs_worker.rb index c9675417aa4..6a48b78b22c 100644 --- a/app/workers/stuck_import_jobs_worker.rb +++ b/app/workers/stuck_import_jobs_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class StuckImportJobsWorker +class StuckImportJobsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker updates several import states inline and does not schedule diff --git a/app/workers/stuck_merge_jobs_worker.rb b/app/workers/stuck_merge_jobs_worker.rb index 9214ae038a8..e0209b8237a 100644 --- a/app/workers/stuck_merge_jobs_worker.rb +++ b/app/workers/stuck_merge_jobs_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class StuckMergeJobsWorker +class StuckMergeJobsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include CronjobQueue # rubocop:disable Scalability/CronWorkerContext diff --git a/app/workers/system_hook_push_worker.rb b/app/workers/system_hook_push_worker.rb index fc6237f359a..ff1f2baf058 100644 --- a/app/workers/system_hook_push_worker.rb +++ b/app/workers/system_hook_push_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class SystemHookPushWorker +class SystemHookPushWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/todos_destroyer/confidential_issue_worker.rb b/app/workers/todos_destroyer/confidential_issue_worker.rb index 240a5f98ad5..b29d4168162 100644 --- a/app/workers/todos_destroyer/confidential_issue_worker.rb +++ b/app/workers/todos_destroyer/confidential_issue_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module TodosDestroyer - class ConfidentialIssueWorker + class ConfidentialIssueWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include TodosDestroyerQueue diff --git a/app/workers/todos_destroyer/entity_leave_worker.rb b/app/workers/todos_destroyer/entity_leave_worker.rb index 7db3f6c84b4..558cc32d158 100644 --- a/app/workers/todos_destroyer/entity_leave_worker.rb +++ b/app/workers/todos_destroyer/entity_leave_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module TodosDestroyer - class EntityLeaveWorker + class EntityLeaveWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include TodosDestroyerQueue diff --git a/app/workers/todos_destroyer/group_private_worker.rb b/app/workers/todos_destroyer/group_private_worker.rb index 21ec4abe478..a1943bee2ec 100644 --- a/app/workers/todos_destroyer/group_private_worker.rb +++ b/app/workers/todos_destroyer/group_private_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module TodosDestroyer - class GroupPrivateWorker + class GroupPrivateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include TodosDestroyerQueue diff --git a/app/workers/todos_destroyer/private_features_worker.rb b/app/workers/todos_destroyer/private_features_worker.rb index 1e68f0fd5ae..6e55467234a 100644 --- a/app/workers/todos_destroyer/private_features_worker.rb +++ b/app/workers/todos_destroyer/private_features_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module TodosDestroyer - class PrivateFeaturesWorker + class PrivateFeaturesWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include TodosDestroyerQueue diff --git a/app/workers/todos_destroyer/project_private_worker.rb b/app/workers/todos_destroyer/project_private_worker.rb index 064e001530c..2a06edc666e 100644 --- a/app/workers/todos_destroyer/project_private_worker.rb +++ b/app/workers/todos_destroyer/project_private_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module TodosDestroyer - class ProjectPrivateWorker + class ProjectPrivateWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include TodosDestroyerQueue diff --git a/app/workers/trending_projects_worker.rb b/app/workers/trending_projects_worker.rb index 208d8b3b9b5..ee7724e0fa8 100644 --- a/app/workers/trending_projects_worker.rb +++ b/app/workers/trending_projects_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class TrendingProjectsWorker +class TrendingProjectsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker # rubocop:disable Scalability/CronWorkerContext # This worker does not perform work scoped to a context diff --git a/app/workers/update_external_pull_requests_worker.rb b/app/workers/update_external_pull_requests_worker.rb index e363b33f1b9..b459d26e487 100644 --- a/app/workers/update_external_pull_requests_worker.rb +++ b/app/workers/update_external_pull_requests_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class UpdateExternalPullRequestsWorker +class UpdateExternalPullRequestsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/update_head_pipeline_for_merge_request_worker.rb b/app/workers/update_head_pipeline_for_merge_request_worker.rb index e069b16eb90..47f0d1e0545 100644 --- a/app/workers/update_head_pipeline_for_merge_request_worker.rb +++ b/app/workers/update_head_pipeline_for_merge_request_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class UpdateHeadPipelineForMergeRequestWorker +class UpdateHeadPipelineForMergeRequestWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include PipelineQueue diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb index ec9739e8a11..195b455f0aa 100644 --- a/app/workers/update_merge_requests_worker.rb +++ b/app/workers/update_merge_requests_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class UpdateMergeRequestsWorker +class UpdateMergeRequestsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/update_project_statistics_worker.rb b/app/workers/update_project_statistics_worker.rb index e36cebf6f4f..336877d9f57 100644 --- a/app/workers/update_project_statistics_worker.rb +++ b/app/workers/update_project_statistics_worker.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true # Worker for updating project statistics. -class UpdateProjectStatisticsWorker +class UpdateProjectStatisticsWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :source_code_management diff --git a/app/workers/upload_checksum_worker.rb b/app/workers/upload_checksum_worker.rb index d35367145b8..dc2511f718c 100644 --- a/app/workers/upload_checksum_worker.rb +++ b/app/workers/upload_checksum_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class UploadChecksumWorker +class UploadChecksumWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :geo_replication diff --git a/app/workers/wait_for_cluster_creation_worker.rb b/app/workers/wait_for_cluster_creation_worker.rb index 621125c8503..2e3feb1a4d1 100644 --- a/app/workers/wait_for_cluster_creation_worker.rb +++ b/app/workers/wait_for_cluster_creation_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class WaitForClusterCreationWorker +class WaitForClusterCreationWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker include ClusterQueue diff --git a/app/workers/web_hook_worker.rb b/app/workers/web_hook_worker.rb index c3fa3162c14..6e1e7e7d62e 100644 --- a/app/workers/web_hook_worker.rb +++ b/app/workers/web_hook_worker.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -class WebHookWorker +class WebHookWorker # rubocop:disable Scalability/IdempotentWorker include ApplicationWorker feature_category :integrations diff --git a/changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml b/changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml new file mode 100644 index 00000000000..def579b44e8 --- /dev/null +++ b/changelogs/unreleased/38096-splitmr-write-resource-milestone-events-pd.yml @@ -0,0 +1,5 @@ +--- +title: Add possibility to track milestone changes on issues and merge requests +merge_request: 24780 +author: +type: added diff --git a/changelogs/unreleased/ak-rescue-error.yml b/changelogs/unreleased/ak-rescue-error.yml new file mode 100644 index 00000000000..2815477d758 --- /dev/null +++ b/changelogs/unreleased/ak-rescue-error.yml @@ -0,0 +1,5 @@ +--- +title: Rescue elasticsearch server error in pod logs +merge_request: 25367 +author: +type: fixed diff --git a/changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml b/changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml new file mode 100644 index 00000000000..7007400ede6 --- /dev/null +++ b/changelogs/unreleased/migrate-fa-spinner-in-views-dashboard-todos.yml @@ -0,0 +1,5 @@ +--- +title: Use new loading spinner in Todos dashboard buttons +merge_request: 25142 +author: Tsegaselassie Tadesse +type: other diff --git a/doc/development/background_migrations.md b/doc/development/background_migrations.md index dfe2312c2fa..9dbfde98766 100644 --- a/doc/development/background_migrations.md +++ b/doc/development/background_migrations.md @@ -72,20 +72,21 @@ migration classes must be defined in the namespace ## Scheduling -Scheduling a background migration should be done in a post-deployment migration. +Scheduling a background migration should be done in a post-deployment +migration that includes `Gitlab::Database::MigrationHelpers` To do so, simply use the following code while replacing the class name and arguments with whatever values are necessary for your migration: ```ruby -BackgroundMigrationWorker.perform_async('BackgroundMigrationClassName', [arg1, arg2, ...]) +migrate_async('BackgroundMigrationClassName', [arg1, arg2, ...]) ``` Usually it's better to enqueue jobs in bulk, for this you can use -`BackgroundMigrationWorker.bulk_perform_async`: +`bulk_migrate_async`: ```ruby -BackgroundMigrationWorker.bulk_perform_async( +bulk_migrate_async( [['BackgroundMigrationClassName', [1]], ['BackgroundMigrationClassName', [2]]] ) @@ -105,7 +106,7 @@ If you would like to schedule jobs in bulk with a delay, you can use jobs = [['BackgroundMigrationClassName', [1]], ['BackgroundMigrationClassName', [2]]] -BackgroundMigrationWorker.bulk_perform_in(5.minutes, jobs) +bulk_migrate_in(5.minutes, jobs) ``` ### Rescheduling background migrations diff --git a/lib/gitlab/database/migration_helpers.rb b/lib/gitlab/database/migration_helpers.rb index 3b6684b861c..6317e034cfb 100644 --- a/lib/gitlab/database/migration_helpers.rb +++ b/lib/gitlab/database/migration_helpers.rb @@ -688,7 +688,7 @@ module Gitlab start_id, end_id = batch.pluck('MIN(id), MAX(id)').first max_index = index - BackgroundMigrationWorker.perform_in( + migrate_in( index * interval, 'CopyColumn', [table, column, temp_column, start_id, end_id] @@ -697,7 +697,7 @@ module Gitlab # Schedule the renaming of the column to happen (initially) 1 hour after # the last batch finished. - BackgroundMigrationWorker.perform_in( + migrate_in( (max_index * interval) + 1.hour, 'CleanupConcurrentTypeChange', [table, column, temp_column] @@ -779,7 +779,7 @@ module Gitlab start_id, end_id = batch.pluck('MIN(id), MAX(id)').first max_index = index - BackgroundMigrationWorker.perform_in( + migrate_in( index * interval, 'CopyColumn', [table, old_column, new_column, start_id, end_id] @@ -788,7 +788,7 @@ module Gitlab # Schedule the renaming of the column to happen (initially) 1 hour after # the last batch finished. - BackgroundMigrationWorker.perform_in( + migrate_in( (max_index * interval) + 1.hour, 'CleanupConcurrentRename', [table, old_column, new_column] @@ -1024,14 +1024,14 @@ into similar problems in the future (e.g. when new tables are created). # We push multiple jobs at a time to reduce the time spent in # Sidekiq/Redis operations. We're using this buffer based approach so we # don't need to run additional queries for every range. - BackgroundMigrationWorker.bulk_perform_async(jobs) + bulk_migrate_async(jobs) jobs.clear end jobs << [job_class_name, [start_id, end_id]] end - BackgroundMigrationWorker.bulk_perform_async(jobs) unless jobs.empty? + bulk_migrate_async(jobs) unless jobs.empty? end # Queues background migration jobs for an entire table, batched by ID range. @@ -1074,7 +1074,7 @@ into similar problems in the future (e.g. when new tables are created). # `BackgroundMigrationWorker.bulk_perform_in` schedules all jobs for # the same time, which is not helpful in most cases where we wish to # spread the work over time. - BackgroundMigrationWorker.perform_in(delay_interval * index, job_class_name, [start_id, end_id]) + migrate_in(delay_interval * index, job_class_name, [start_id, end_id]) end end @@ -1133,6 +1133,30 @@ into similar problems in the future (e.g. when new tables are created). execute(sql) end + def migrate_async(*args) + with_migration_context do + BackgroundMigrationWorker.perform_async(*args) + end + end + + def migrate_in(*args) + with_migration_context do + BackgroundMigrationWorker.perform_in(*args) + end + end + + def bulk_migrate_in(*args) + with_migration_context do + BackgroundMigrationWorker.bulk_perform_in(*args) + end + end + + def bulk_migrate_async(*args) + with_migration_context do + BackgroundMigrationWorker.bulk_perform_async(*args) + end + end + private def tables_match?(target_table, foreign_key_table) @@ -1191,6 +1215,10 @@ into similar problems in the future (e.g. when new tables are created). your migration class ERROR end + + def with_migration_context(&block) + Gitlab::ApplicationContext.with_context(caller_id: self.class.to_s, &block) + end end end end diff --git a/lib/gitlab/sidekiq_config/dummy_worker.rb b/lib/gitlab/sidekiq_config/dummy_worker.rb index 858ff0db0c9..c2c8354b662 100644 --- a/lib/gitlab/sidekiq_config/dummy_worker.rb +++ b/lib/gitlab/sidekiq_config/dummy_worker.rb @@ -11,6 +11,7 @@ module Gitlab has_external_dependencies: :worker_has_external_dependencies?, latency_sensitive: :latency_sensitive_worker?, resource_boundary: :get_worker_resource_boundary, + idempotent: :idempotent?, weight: :get_weight }.freeze diff --git a/lib/gitlab/sidekiq_config/worker.rb b/lib/gitlab/sidekiq_config/worker.rb index 6cbe327e6b2..4046ef54383 100644 --- a/lib/gitlab/sidekiq_config/worker.rb +++ b/lib/gitlab/sidekiq_config/worker.rb @@ -7,7 +7,7 @@ module Gitlab attr_reader :klass delegate :feature_category_not_owned?, :get_feature_category, - :get_weight, :get_worker_resource_boundary, + :get_weight, :get_worker_resource_boundary, :idempotent?, :latency_sensitive_worker?, :queue, :queue_namespace, :worker_has_external_dependencies?, to: :klass @@ -51,7 +51,8 @@ module Gitlab has_external_dependencies: worker_has_external_dependencies?, latency_sensitive: latency_sensitive_worker?, resource_boundary: get_worker_resource_boundary, - weight: get_weight + weight: get_weight, + idempotent: idempotent? } end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index e0209671160..e8418b34f2d 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -7044,6 +7044,9 @@ msgstr "" msgid "Elasticsearch integration. Elasticsearch AWS IAM." msgstr "" +msgid "Elasticsearch returned status code: %{status_code}" +msgstr "" + msgid "Elastic|None. Select namespaces to index." msgstr "" diff --git a/rubocop/cop/migration/schedule_async.rb b/rubocop/cop/migration/schedule_async.rb new file mode 100644 index 00000000000..f296628c3d6 --- /dev/null +++ b/rubocop/cop/migration/schedule_async.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require_relative '../../migration_helpers' + +module RuboCop + module Cop + module Migration + class ScheduleAsync < RuboCop::Cop::Cop + include MigrationHelpers + + ENFORCED_SINCE = 2020_02_12_00_00_00 + + MSG = <<~MSG + Don't call the background migration worker directly, use the `#migrate_async`, + `#migrate_in`, `#bulk_migrate_async` or `#bulk_migrate_in` migration helpers + instead. + MSG + + def_node_matcher :calls_background_migration_worker?, <<~PATTERN + (send (const nil? :BackgroundMigrationWorker) {:perform_async :perform_in :bulk_perform_async :bulk_perform_in} ... ) + PATTERN + + def on_send(node) + return unless in_migration?(node) + return if version(node) < ENFORCED_SINCE + + add_offense(node, location: :expression) if calls_background_migration_worker?(node) + end + + def autocorrect(node) + # This gets rid of the receiver `BackgroundMigrationWorker` and + # replaces `perform` with `schedule` + schedule_method = method_name(node).to_s.sub('perform', 'migrate') + arguments = arguments(node).map(&:source).join(', ') + + replacement = "#{schedule_method}(#{arguments})" + lambda do |corrector| + corrector.replace(node.source_range, replacement) + end + end + + private + + def method_name(node) + node.children.second + end + + def arguments(node) + node.children[2..-1] + end + end + end + end +end diff --git a/rubocop/cop/scalability/idempotent_worker.rb b/rubocop/cop/scalability/idempotent_worker.rb new file mode 100644 index 00000000000..a38b457b7c7 --- /dev/null +++ b/rubocop/cop/scalability/idempotent_worker.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require_relative '../../code_reuse_helpers.rb' + +module RuboCop + module Cop + module Scalability + # This cop checks for the `idempotent!` call in the worker scope. + # + # @example + # + # # bad + # class TroubleMakerWorker + # def perform + # end + # end + # + # # good + # class NiceWorker + # idempotent! + # + # def perform + # end + # end + # + class IdempotentWorker < RuboCop::Cop::Cop + include CodeReuseHelpers + + HELP_LINK = 'https://github.com/mperham/sidekiq/wiki/Best-Practices#2-make-your-job-idempotent-and-transactional' + + MSG = <<~MSG + Avoid adding not idempotent workers. + + A worker is considered idempotent if: + + 1. It can safely run multiple times with the same arguments + 2. The application side-effects are expected to happen once (or side-effects of a second run are not impactful) + 3. It can safely be skipped if another job with the same arguments is already in the queue + + If all the above is true, make sure to mark it as so by calling the `idempotent!` + method in the worker scope. + + See #{HELP_LINK} + MSG + + def_node_search :idempotent?, <<~PATTERN + (send nil? :idempotent!) + PATTERN + + def on_class(node) + return unless in_worker?(node) + return if idempotent?(node) + + add_offense(node, location: :expression) + end + end + end + end +end diff --git a/rubocop/migration_helpers.rb b/rubocop/migration_helpers.rb index 577f768da67..767cacaecaf 100644 --- a/rubocop/migration_helpers.rb +++ b/rubocop/migration_helpers.rb @@ -10,6 +10,10 @@ module RuboCop dirname(node).end_with?('db/post_migrate', 'db/geo/post_migrate') end + def version(node) + File.basename(node.location.expression.source_buffer.name).split('_').first.to_i + end + private def dirname(node) diff --git a/spec/controllers/projects/milestones_controller_spec.rb b/spec/controllers/projects/milestones_controller_spec.rb index 6b698c6da66..ee61ef73b45 100644 --- a/spec/controllers/projects/milestones_controller_spec.rb +++ b/spec/controllers/projects/milestones_controller_spec.rb @@ -135,6 +135,10 @@ describe Projects::MilestonesController do end describe "#destroy" do + before do + stub_feature_flags(track_resource_milestone_change_events: false) + end + it "removes milestone" do expect(issue.milestone_id).to eq(milestone.id) diff --git a/spec/factories/resource_milestone_event.rb b/spec/factories/resource_milestone_event.rb new file mode 100644 index 00000000000..86c54f2be68 --- /dev/null +++ b/spec/factories/resource_milestone_event.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :resource_milestone_event do + issue { merge_request.nil? ? create(:issue) : nil } + merge_request { nil } + milestone + action { :add } + state { :opened } + user { issue&.author || merge_request&.author || create(:user) } + end +end diff --git a/spec/lib/gitlab/database/migration_helpers_spec.rb b/spec/lib/gitlab/database/migration_helpers_spec.rb index 4cf2553b90d..bb5475130cf 100644 --- a/spec/lib/gitlab/database/migration_helpers_spec.rb +++ b/spec/lib/gitlab/database/migration_helpers_spec.rb @@ -1893,4 +1893,60 @@ describe Gitlab::Database::MigrationHelpers do end end end + + describe '#migrate_async' do + it 'calls BackgroundMigrationWorker.perform_async' do + expect(BackgroundMigrationWorker).to receive(:perform_async).with("Class", "hello", "world") + + model.migrate_async("Class", "hello", "world") + end + + it 'pushes a context with the current class name as caller_id' do + expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s) + + model.migrate_async('Class', 'hello', 'world') + end + end + + describe '#migrate_in' do + it 'calls BackgroundMigrationWorker.perform_in' do + expect(BackgroundMigrationWorker).to receive(:perform_in).with(10.minutes, 'Class', 'Hello', 'World') + + model.migrate_in(10.minutes, 'Class', 'Hello', 'World') + end + + it 'pushes a context with the current class name as caller_id' do + expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s) + + model.migrate_in(10.minutes, 'Class', 'Hello', 'World') + end + end + + describe '#bulk_migrate_async' do + it 'calls BackgroundMigrationWorker.bulk_perform_async' do + expect(BackgroundMigrationWorker).to receive(:bulk_perform_async).with([%w(Class hello world)]) + + model.bulk_migrate_async([%w(Class hello world)]) + end + + it 'pushes a context with the current class name as caller_id' do + expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s) + + model.bulk_migrate_async([%w(Class hello world)]) + end + end + + describe '#bulk_migrate_in' do + it 'calls BackgroundMigrationWorker.bulk_perform_in_' do + expect(BackgroundMigrationWorker).to receive(:bulk_perform_in).with(10.minutes, [%w(Class hello world)]) + + model.bulk_migrate_in(10.minutes, [%w(Class hello world)]) + end + + it 'pushes a context with the current class name as caller_id' do + expect(Gitlab::ApplicationContext).to receive(:with_context).with(caller_id: model.class.to_s) + + model.bulk_migrate_in(10.minutes, [%w(Class hello world)]) + end + end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 4dadb310029..6c9a4bbfc71 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -9,6 +9,7 @@ issues: - notes - resource_label_events - resource_weight_events +- resource_milestone_events - sentry_issue - label_links - labels @@ -109,6 +110,7 @@ merge_requests: - milestone - notes - resource_label_events +- resource_milestone_events - label_links - labels - last_edited_by diff --git a/spec/lib/gitlab/sidekiq_config/worker_spec.rb b/spec/lib/gitlab/sidekiq_config/worker_spec.rb index 38edd0f5eeb..fcdce8f9432 100644 --- a/spec/lib/gitlab/sidekiq_config/worker_spec.rb +++ b/spec/lib/gitlab/sidekiq_config/worker_spec.rb @@ -12,7 +12,8 @@ describe Gitlab::SidekiqConfig::Worker do get_weight: attributes[:weight], get_worker_resource_boundary: attributes[:resource_boundary], latency_sensitive_worker?: attributes[:latency_sensitive], - worker_has_external_dependencies?: attributes[:has_external_dependencies] + worker_has_external_dependencies?: attributes[:has_external_dependencies], + idempotent?: attributes[:idempotent] ) described_class.new(inner_worker, ee: false) @@ -89,7 +90,8 @@ describe Gitlab::SidekiqConfig::Worker do has_external_dependencies: false, latency_sensitive: false, resource_boundary: :memory, - weight: 2 + weight: 2, + idempotent: true } attributes_b = { @@ -97,7 +99,8 @@ describe Gitlab::SidekiqConfig::Worker do has_external_dependencies: true, latency_sensitive: true, resource_boundary: :unknown, - weight: 1 + weight: 3, + idempotent: false } worker_a = create_worker(queue: 'a', **attributes_a) diff --git a/spec/models/milestone_note_spec.rb b/spec/models/milestone_note_spec.rb new file mode 100644 index 00000000000..9e77ef91bb2 --- /dev/null +++ b/spec/models/milestone_note_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe MilestoneNote do + describe '.from_event' do + let(:author) { create(:user) } + let(:project) { create(:project, :repository) } + let(:noteable) { create(:issue, author: author, project: project) } + let(:event) { create(:resource_milestone_event, issue: noteable) } + + subject { described_class.from_event(event, resource: noteable, resource_parent: project) } + + it_behaves_like 'a system note', exclude_project: true do + let(:action) { 'milestone' } + end + end +end diff --git a/spec/models/resource_milestone_event_spec.rb b/spec/models/resource_milestone_event_spec.rb new file mode 100644 index 00000000000..1b0181e3fd2 --- /dev/null +++ b/spec/models/resource_milestone_event_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ResourceMilestoneEvent, type: :model do + it_behaves_like 'a resource event' + it_behaves_like 'a resource event for issues' + it_behaves_like 'a resource event for merge requests' + + it_behaves_like 'having unique enum values' + + describe 'associations' do + it { is_expected.to belong_to(:milestone) } + end + + describe 'validations' do + context 'when issue and merge_request are both nil' do + subject { build(described_class.name.underscore.to_sym, issue: nil, merge_request: nil) } + + it { is_expected.not_to be_valid } + end + + context 'when issue and merge_request are both set' do + subject { build(described_class.name.underscore.to_sym, issue: build(:issue), merge_request: build(:merge_request)) } + + it { is_expected.not_to be_valid } + end + + context 'when issue is set' do + subject { create(described_class.name.underscore.to_sym, issue: create(:issue), merge_request: nil) } + + it { is_expected.to be_valid } + end + + context 'when merge_request is set' do + subject { create(described_class.name.underscore.to_sym, issue: nil, merge_request: create(:merge_request)) } + + it { is_expected.to be_valid } + end + end + + describe 'states' do + [Issue, MergeRequest].each do |klass| + klass.available_states.each do |state| + it "supports state #{state.first} for #{klass.name.underscore}" do + model = create(klass.name.underscore, state: state[0]) + key = model.class.name.underscore + event = build(described_class.name.underscore.to_sym, key => model, state: model.state) + + expect(event.state).to eq(state[0]) + end + end + end + end +end diff --git a/spec/rubocop/cop/migration/schedule_async_spec.rb b/spec/rubocop/cop/migration/schedule_async_spec.rb new file mode 100644 index 00000000000..3453f1c51cc --- /dev/null +++ b/spec/rubocop/cop/migration/schedule_async_spec.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +require 'rubocop' +require 'rubocop/rspec/support' + +require_relative '../../../../rubocop/cop/migration/schedule_async' + +describe RuboCop::Cop::Migration::ScheduleAsync do + include CopHelper + + let(:cop) { described_class.new } + let(:source) do + <<~SOURCE + def up + BackgroundMigrationWorker.perform_async(ClazzName, "Bar", "Baz") + end + SOURCE + end + + shared_examples 'a disabled cop' do + it 'does not register any offenses' do + inspect_source(source) + + expect(cop.offenses).to be_empty + end + end + + context 'outside of a migration' do + it_behaves_like 'a disabled cop' + end + + context 'in a migration' do + before do + allow(cop).to receive(:in_migration?).and_return(true) + end + + context 'in an old migration' do + before do + allow(cop).to receive(:version).and_return(described_class::ENFORCED_SINCE - 5) + end + + it_behaves_like 'a disabled cop' + end + + context 'that is recent' do + before do + allow(cop).to receive(:version).and_return(described_class::ENFORCED_SINCE + 5) + end + + context 'BackgroundMigrationWorker.perform_async' do + it 'adds an offence when calling `BackgroundMigrationWorker.peform_async`' do + inspect_source(source) + + expect(cop.offenses.size).to eq(1) + end + + it 'autocorrects to the right version' do + correct_source = <<~CORRECT + def up + migrate_async(ClazzName, "Bar", "Baz") + end + CORRECT + + expect(autocorrect_source(source)).to eq(correct_source) + end + end + + context 'BackgroundMigrationWorker.perform_in' do + let(:source) do + <<~SOURCE + def up + BackgroundMigrationWorker + .perform_in(delay, ClazzName, "Bar", "Baz") + end + SOURCE + end + + it 'adds an offence' do + inspect_source(source) + + expect(cop.offenses.size).to eq(1) + end + + it 'autocorrects to the right version' do + correct_source = <<~CORRECT + def up + migrate_in(delay, ClazzName, "Bar", "Baz") + end + CORRECT + + expect(autocorrect_source(source)).to eq(correct_source) + end + end + + context 'BackgroundMigrationWorker.bulk_perform_async' do + let(:source) do + <<~SOURCE + def up + BackgroundMigrationWorker + .bulk_perform_async(jobs) + end + SOURCE + end + + it 'adds an offence' do + inspect_source(source) + + expect(cop.offenses.size).to eq(1) + end + + it 'autocorrects to the right version' do + correct_source = <<~CORRECT + def up + bulk_migrate_async(jobs) + end + CORRECT + + expect(autocorrect_source(source)).to eq(correct_source) + end + end + + context 'BackgroundMigrationWorker.bulk_perform_in' do + let(:source) do + <<~SOURCE + def up + BackgroundMigrationWorker + .bulk_perform_in(5.minutes, jobs) + end + SOURCE + end + + it 'adds an offence' do + inspect_source(source) + + expect(cop.offenses.size).to eq(1) + end + + it 'autocorrects to the right version' do + correct_source = <<~CORRECT + def up + bulk_migrate_in(5.minutes, jobs) + end + CORRECT + + expect(autocorrect_source(source)).to eq(correct_source) + end + end + end + end +end diff --git a/spec/rubocop/cop/scalability/idempotent_worker_spec.rb b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb new file mode 100644 index 00000000000..7abd602f8bc --- /dev/null +++ b/spec/rubocop/cop/scalability/idempotent_worker_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require 'rubocop' +require_relative '../../../support/helpers/expect_offense' +require_relative '../../../../rubocop/cop/scalability/idempotent_worker' + +describe RuboCop::Cop::Scalability::IdempotentWorker do + include CopHelper + include ExpectOffense + + subject(:cop) { described_class.new } + + before do + allow(cop) + .to receive(:in_worker?) + .and_return(true) + end + + it 'adds an offense when not defining idempotent method' do + inspect_source(<<~CODE.strip_indent) + class SomeWorker + end + CODE + + expect(cop.offenses.size).to eq(1) + end + + it 'adds an offense when not defining idempotent method' do + inspect_source(<<~CODE.strip_indent) + class SomeWorker + idempotent! + end + CODE + + expect(cop.offenses.size).to be_zero + end +end diff --git a/spec/rubocop/migration_helpers_spec.rb b/spec/rubocop/migration_helpers_spec.rb new file mode 100644 index 00000000000..73ced8c58da --- /dev/null +++ b/spec/rubocop/migration_helpers_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require 'rubocop' +require 'rspec-parameterized' + +require_relative '../../rubocop/migration_helpers' + +describe RuboCop::MigrationHelpers do + using RSpec::Parameterized::TableSyntax + + subject(:fake_cop) { Class.new { include RuboCop::MigrationHelpers }.new } + + let(:node) { double(:node) } + + before do + allow(node).to receive_message_chain('location.expression.source_buffer.name') + .and_return(name) + end + + describe '#in_migration?' do + where(:name, :expected) do + '/gitlab/db/migrate/20200210184420_create_operations_scopes_table.rb' | true + '/gitlab/db/post_migrate/20200210184420_create_operations_scopes_table.rb' | true + '/gitlab/db/geo/migrate/20200210184420_create_operations_scopes_table.rb' | true + '/gitlab/db/geo/post_migrate/20200210184420_create_operations_scopes_table.rb' | true + '/gitlab/db/elsewhere/20200210184420_create_operations_scopes_table.rb' | false + end + + with_them do + it { expect(fake_cop.in_migration?(node)).to eq(expected) } + end + end + + describe '#in_post_deployment_migration?' do + where(:name, :expected) do + '/gitlab/db/migrate/20200210184420_create_operations_scopes_table.rb' | false + '/gitlab/db/post_migrate/20200210184420_create_operations_scopes_table.rb' | true + '/gitlab/db/geo/migrate/20200210184420_create_operations_scopes_table.rb' | false + '/gitlab/db/geo/post_migrate/20200210184420_create_operations_scopes_table.rb' | true + '/gitlab/db/elsewhere/20200210184420_create_operations_scopes_table.rb' | false + end + + with_them do + it { expect(fake_cop.in_post_deployment_migration?(node)).to eq(expected) } + end + end + + describe "#version" do + let(:name) do + '/path/to/gitlab/db/migrate/20200210184420_create_operations_scopes_table.rb' + end + + it { expect(fake_cop.version(node)).to eq(20200210184420) } + end +end diff --git a/spec/services/issuable/clone/attributes_rewriter_spec.rb b/spec/services/issuable/clone/attributes_rewriter_spec.rb index 20bda6984bd..6bc0df8260b 100644 --- a/spec/services/issuable/clone/attributes_rewriter_spec.rb +++ b/spec/services/issuable/clone/attributes_rewriter_spec.rb @@ -75,5 +75,47 @@ describe Issuable::Clone::AttributesRewriter do expect(new_issue.reload.milestone).to eq(milestone) end + + context 'with existing milestone events' do + let!(:milestone1_project1) { create(:milestone, title: 'milestone1', project: project1) } + let!(:milestone2_project1) { create(:milestone, title: 'milestone2', project: project1) } + let!(:milestone3_project1) { create(:milestone, title: 'milestone3', project: project1) } + + let!(:milestone1_project2) { create(:milestone, title: 'milestone1', project: project2) } + let!(:milestone2_project2) { create(:milestone, title: 'milestone2', project: project2) } + + before do + original_issue.update(milestone: milestone2_project1) + + create_event(milestone1_project1) + create_event(milestone2_project1) + create_event(milestone1_project1, 'remove') + create_event(milestone3_project1) + end + + it 'copies existing resource milestone events' do + subject.execute + + new_issue_milestone_events = new_issue.reload.resource_milestone_events + expect(new_issue_milestone_events.count).to eq(3) + + expect_milestone_event(new_issue_milestone_events.first, milestone: milestone1_project2, action: 'add', state: 'opened') + expect_milestone_event(new_issue_milestone_events.second, milestone: milestone2_project2, action: 'add', state: 'opened') + expect_milestone_event(new_issue_milestone_events.third, milestone: milestone1_project2, action: 'remove', state: 'opened') + end + + def create_event(milestone, action = 'add') + create(:resource_milestone_event, issue: original_issue, milestone: milestone, action: action) + end + + def expect_milestone_event(event, expected_attrs) + expect(event.milestone_id).to eq(expected_attrs[:milestone].id) + expect(event.action).to eq(expected_attrs[:action]) + expect(event.state).to eq(expected_attrs[:state]) + + expect(event.reference).to be_nil + expect(event.reference_html).to be_nil + end + end end end diff --git a/spec/services/issuable/common_system_notes_service_spec.rb b/spec/services/issuable/common_system_notes_service_spec.rb index 7e40ac9ff4d..771e7ca42c9 100644 --- a/spec/services/issuable/common_system_notes_service_spec.rb +++ b/spec/services/issuable/common_system_notes_service_spec.rb @@ -3,8 +3,9 @@ require 'spec_helper' describe Issuable::CommonSystemNotesService do - let(:user) { create(:user) } - let(:project) { create(:project) } + let_it_be(:project) { create(:project) } + let_it_be(:user) { create(:user) } + let(:issuable) { create(:issue, project: project) } context 'on issuable update' do @@ -35,6 +36,8 @@ describe Issuable::CommonSystemNotesService do before do milestone = create(:milestone, project: project) issuable.milestone_id = milestone.id + + stub_feature_flags(track_resource_milestone_change_events: false) end it_behaves_like 'system note creation', {}, 'changed milestone' @@ -97,12 +100,39 @@ describe Issuable::CommonSystemNotesService do expect(event.user_id).to eq user.id end - it 'creates a system note for milestone set' do - issuable.milestone = create(:milestone, project: project) - issuable.save + context 'when milestone change event tracking is disabled' do + before do + stub_feature_flags(track_resource_milestone_change_events: false) - expect { subject }.to change { issuable.notes.count }.from(0).to(1) - expect(issuable.notes.last.note).to match('changed milestone') + issuable.milestone = create(:milestone, project: project) + issuable.save + end + + it 'creates a system note for milestone set' do + expect { subject }.to change { issuable.notes.count }.from(0).to(1) + expect(issuable.notes.last.note).to match('changed milestone') + end + + it 'does not create a milestone change event' do + expect { subject }.not_to change { ResourceMilestoneEvent.count } + end + end + + context 'when milestone change event tracking is enabled' do + let_it_be(:milestone) { create(:milestone, project: project) } + let_it_be(:issuable) { create(:issue, project: project, milestone: milestone) } + + before do + stub_feature_flags(track_resource_milestone_change_events: true) + end + + it 'does not create a system note for milestone set' do + expect { subject }.not_to change { issuable.notes.count } + end + + it 'creates a milestone change event' do + expect { subject }.to change { ResourceMilestoneEvent.count }.from(0).to(1) + end end it 'creates a system note for due_date set' do diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 888a63980f6..5da77dd914c 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -385,6 +385,10 @@ describe Issues::UpdateService, :mailer do end context 'when the milestone is removed' do + before do + stub_feature_flags(track_resource_milestone_change_events: false) + end + let!(:non_subscriber) { create(:user) } let!(:subscriber) do @@ -411,6 +415,10 @@ describe Issues::UpdateService, :mailer do end context 'when the milestone is changed' do + before do + stub_feature_flags(track_resource_milestone_change_events: false) + end + let!(:non_subscriber) { create(:user) } let!(:subscriber) do diff --git a/spec/services/merge_requests/update_service_spec.rb b/spec/services/merge_requests/update_service_spec.rb index f295f3c4a81..dd5d90b2d07 100644 --- a/spec/services/merge_requests/update_service_spec.rb +++ b/spec/services/merge_requests/update_service_spec.rb @@ -367,6 +367,10 @@ describe MergeRequests::UpdateService, :mailer do end context 'when the milestone is removed' do + before do + stub_feature_flags(track_resource_milestone_change_events: false) + end + let!(:non_subscriber) { create(:user) } let!(:subscriber) do @@ -393,6 +397,10 @@ describe MergeRequests::UpdateService, :mailer do end context 'when the milestone is changed' do + before do + stub_feature_flags(track_resource_milestone_change_events: false) + end + let!(:non_subscriber) { create(:user) } let!(:subscriber) do diff --git a/spec/services/resource_events/change_milestone_service_spec.rb b/spec/services/resource_events/change_milestone_service_spec.rb new file mode 100644 index 00000000000..c6b4f8e1b7e --- /dev/null +++ b/spec/services/resource_events/change_milestone_service_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe ResourceEvents::ChangeMilestoneService do + shared_examples 'milestone events creator' do + let_it_be(:user) { create(:user) } + + let_it_be(:milestone) { create(:milestone) } + + context 'when milestone is present' do + before do + resource.milestone = milestone + end + + let(:service) { described_class.new(resource: resource, user: user, created_at: created_at_time) } + + it 'creates the expected event record' do + expect { service.execute }.to change { ResourceMilestoneEvent.count }.from(0).to(1) + + events = ResourceMilestoneEvent.all + + expect(events.size).to eq(1) + expect_event_record(events.first, action: 'add', milestone: milestone, state: 'opened') + end + end + + context 'when milestones is not present' do + before do + resource.milestone = nil + end + + let(:service) { described_class.new(resource: resource, user: user, created_at: created_at_time) } + + it 'creates the expected event records' do + expect { service.execute }.to change { ResourceMilestoneEvent.count }.from(0).to(1) + + expect_event_record(ResourceMilestoneEvent.first, action: 'remove', milestone: nil, state: 'opened') + end + end + + def expect_event_record(event, expected_attrs) + expect(event.action).to eq(expected_attrs[:action]) + expect(event.state).to eq(expected_attrs[:state]) + expect(event.user).to eq(user) + expect(event.issue).to eq(resource) if resource.is_a?(Issue) + expect(event.issue).to be_nil unless resource.is_a?(Issue) + expect(event.merge_request).to eq(resource) if resource.is_a?(MergeRequest) + expect(event.merge_request).to be_nil unless resource.is_a?(MergeRequest) + expect(event.milestone).to eq(expected_attrs[:milestone]) + expect(event.created_at).to eq(created_at_time) + end + end + + let_it_be(:merge_request) { create(:merge_request) } + let_it_be(:issue) { create(:issue) } + + let!(:created_at_time) { Time.utc(2019, 12, 30) } + + it_behaves_like 'milestone events creator' do + let(:resource) { issue } + end + + it_behaves_like 'milestone events creator' do + let(:resource) { merge_request } + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 35bf6846ab3..b862fc4bbd9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -119,6 +119,7 @@ RSpec.configure do |config| config.include PolicyHelpers, type: :policy config.include MemoryUsageHelper config.include ExpectRequestWithStatus, type: :request + config.include IdempotentWorkerHelper, type: :worker config.include RailsHelpers if ENV['CI'] || ENV['RETRIES'] diff --git a/spec/support/helpers/idempotent_worker_helper.rb b/spec/support/helpers/idempotent_worker_helper.rb new file mode 100644 index 00000000000..b80758d10bd --- /dev/null +++ b/spec/support/helpers/idempotent_worker_helper.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module IdempotentWorkerHelper + WORKER_EXEC_TIMES = 2 + + def perform_multiple(args = [], worker: described_class.new, exec_times: WORKER_EXEC_TIMES) + Sidekiq::Testing.inline! do + job_args = args.nil? ? [nil] : Array.wrap(args) + + expect(worker).to receive(:perform).exactly(exec_times).and_call_original + + exec_times.times { worker.perform(*job_args) } + end + end +end diff --git a/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb b/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb index 897a962fc56..32c46753006 100644 --- a/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb +++ b/spec/support/shared_examples/quick_actions/issue/move_quick_action_shared_examples.rb @@ -50,6 +50,8 @@ RSpec.shared_examples 'move quick action' do let(:bug) { create(:label, project: project, title: 'bug') } let(:wontfix) { create(:label, project: project, title: 'wontfix') } + let!(:target_milestone) { create(:milestone, title: '1.0', project: target_project) } + before do target_project.add_maintainer(user) end diff --git a/spec/support/shared_examples/resource_events.rb b/spec/support/shared_examples/resource_events.rb new file mode 100644 index 00000000000..d7e7349ad6c --- /dev/null +++ b/spec/support/shared_examples/resource_events.rb @@ -0,0 +1,104 @@ +# frozen_string_literal: true + +require 'spec_helper' + +shared_examples 'a resource event' do + let_it_be(:user1) { create(:user) } + let_it_be(:user2) { create(:user) } + + let_it_be(:issue1) { create(:issue, author: user1) } + let_it_be(:issue2) { create(:issue, author: user1) } + let_it_be(:issue3) { create(:issue, author: user2) } + + describe 'validations' do + it { is_expected.not_to allow_value(nil).for(:user) } + end + + describe 'associations' do + it { is_expected.to belong_to(:user) } + end + + describe '.created_after' do + let!(:created_at1) { 1.day.ago } + let!(:created_at2) { 2.days.ago } + let!(:created_at3) { 3.days.ago } + + let!(:event1) { create(described_class.name.underscore.to_sym, issue: issue1, created_at: created_at1) } + let!(:event2) { create(described_class.name.underscore.to_sym, issue: issue2, created_at: created_at2) } + let!(:event3) { create(described_class.name.underscore.to_sym, issue: issue2, created_at: created_at3) } + + it 'returns the expected events' do + events = described_class.created_after(created_at3) + + expect(events).to contain_exactly(event1, event2) + end + + it 'returns no events if time is after last record time' do + events = described_class.created_after(1.minute.ago) + + expect(events).to be_empty + end + end +end + +shared_examples 'a resource event for issues' do + let_it_be(:user1) { create(:user) } + let_it_be(:user2) { create(:user) } + + let_it_be(:issue1) { create(:issue, author: user1) } + let_it_be(:issue2) { create(:issue, author: user1) } + let_it_be(:issue3) { create(:issue, author: user2) } + + describe 'associations' do + it { is_expected.to belong_to(:issue) } + end + + describe '.by_issue' do + let_it_be(:event1) { create(described_class.name.underscore.to_sym, issue: issue1) } + let_it_be(:event2) { create(described_class.name.underscore.to_sym, issue: issue2) } + let_it_be(:event3) { create(described_class.name.underscore.to_sym, issue: issue1) } + + it 'returns the expected records for an issue with events' do + events = described_class.by_issue(issue1) + + expect(events).to contain_exactly(event1, event3) + end + + it 'returns the expected records for an issue with no events' do + events = described_class.by_issue(issue3) + + expect(events).to be_empty + end + end +end + +shared_examples 'a resource event for merge requests' do + let_it_be(:user1) { create(:user) } + let_it_be(:user2) { create(:user) } + + let_it_be(:merge_request1) { create(:merge_request, author: user1) } + let_it_be(:merge_request2) { create(:merge_request, author: user1) } + let_it_be(:merge_request3) { create(:merge_request, author: user2) } + + describe 'associations' do + it { is_expected.to belong_to(:merge_request) } + end + + describe '.by_merge_request' do + let_it_be(:event1) { create(described_class.name.underscore.to_sym, merge_request: merge_request1) } + let_it_be(:event2) { create(described_class.name.underscore.to_sym, merge_request: merge_request2) } + let_it_be(:event3) { create(described_class.name.underscore.to_sym, merge_request: merge_request1) } + + it 'returns the expected records for an issue with events' do + events = described_class.by_merge_request(merge_request1) + + expect(events).to contain_exactly(event1, event3) + end + + it 'returns the expected records for an issue with no events' do + events = described_class.by_merge_request(merge_request3) + + expect(events).to be_empty + end + end +end diff --git a/spec/support/shared_examples/workers/idempotency_shared_examples.rb b/spec/support/shared_examples/workers/idempotency_shared_examples.rb new file mode 100644 index 00000000000..19be1fe2c9d --- /dev/null +++ b/spec/support/shared_examples/workers/idempotency_shared_examples.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +# This shared_example requires the following variables: +# - job_args (if not given, will fallback to call perform without arguments) +# +# Usage: +# +# include_examples 'an idempotent worker' do +# it 'checks the side-effects for multiple calls' do +# # it'll call the job's perform method 3 times +# # by default. +# subject +# +# expect(model.state).to eq('state') +# end +# end +# +RSpec.shared_examples 'an idempotent worker' do + # Avoid stubbing calls for a more accurate run. + subject do + defined?(job_args) ? perform_multiple(job_args) : perform_multiple + end + + it 'is labeled as idempotent' do + expect(described_class).to be_idempotent + end + + it 'performs multiple times sequentially without raising an exception' do + expect { subject }.not_to raise_error + end +end diff --git a/spec/workers/background_migration_worker_spec.rb b/spec/workers/background_migration_worker_spec.rb index aae6fa02a0c..2b2ffc9f5b9 100644 --- a/spec/workers/background_migration_worker_spec.rb +++ b/spec/workers/background_migration_worker_spec.rb @@ -11,7 +11,7 @@ describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do end end - describe '.perform' do + describe '#perform' do it 'performs a background migration' do expect(Gitlab::BackgroundMigration) .to receive(:perform) @@ -52,6 +52,14 @@ describe BackgroundMigrationWorker, :clean_gitlab_redis_shared_state do worker.perform('Foo', [10, 20]) end + + it 'sets the class that will be executed as the caller_id' do + expect(Gitlab::BackgroundMigration).to receive(:perform) do + expect(Labkit::Context.current.to_h).to include('meta.caller_id' => 'Foo') + end + + worker.perform('Foo', [10, 20]) + end end describe '#healthy_database?' do diff --git a/spec/workers/expire_job_cache_worker_spec.rb b/spec/workers/expire_job_cache_worker_spec.rb index eeab304d926..ebca7020ee5 100644 --- a/spec/workers/expire_job_cache_worker_spec.rb +++ b/spec/workers/expire_job_cache_worker_spec.rb @@ -6,20 +6,32 @@ describe ExpireJobCacheWorker do set(:pipeline) { create(:ci_empty_pipeline) } let(:project) { pipeline.project } - subject { described_class.new } - describe '#perform' do context 'with a job in the pipeline' do let(:job) { create(:ci_build, pipeline: pipeline) } + let(:job_args) { job.id } - it 'invalidates Etag caching for the job path' do - pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" - job_path = "/#{project.full_path}/builds/#{job.id}.json" + include_examples 'an idempotent worker' do + it 'invalidates Etag caching for the job path' do + pipeline_path = "/#{project.full_path}/pipelines/#{pipeline.id}.json" + job_path = "/#{project.full_path}/builds/#{job.id}.json" - expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(pipeline_path) - expect_any_instance_of(Gitlab::EtagCaching::Store).to receive(:touch).with(job_path) + spy_store = Gitlab::EtagCaching::Store.new - subject.perform(job.id) + allow(Gitlab::EtagCaching::Store).to receive(:new) { spy_store } + + expect(spy_store).to receive(:touch) + .exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times + .with(pipeline_path) + .and_call_original + + expect(spy_store).to receive(:touch) + .exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times + .with(job_path) + .and_call_original + + subject + end end end @@ -27,7 +39,7 @@ describe ExpireJobCacheWorker do it 'does not change the etag store' do expect(Gitlab::EtagCaching::Store).not_to receive(:new) - subject.perform(9999) + perform_multiple(9999) end end end