diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-03 12:08:44 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-03 12:08:44 +0300 |
commit | b4c39709e346f437a85829f985f6596cb6209d35 (patch) | |
tree | 010b87019e3f523045141f3ce683a1f5d4141499 /app/services/ci | |
parent | ea044b0c4c74b91c5d48435254e7fa60aea064ff (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/services/ci')
-rw-r--r-- | app/services/ci/refs/enqueue_pipelines_to_unlock_service.rb | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/app/services/ci/refs/enqueue_pipelines_to_unlock_service.rb b/app/services/ci/refs/enqueue_pipelines_to_unlock_service.rb index 319186ce030..4e9e9a2effe 100644 --- a/app/services/ci/refs/enqueue_pipelines_to_unlock_service.rb +++ b/app/services/ci/refs/enqueue_pipelines_to_unlock_service.rb @@ -7,13 +7,12 @@ module Ci BATCH_SIZE = 50 ENQUEUE_INTERVAL_SECONDS = 0.1 + EXCLUDED_IDS_LIMIT = 1000 def execute(ci_ref, before_pipeline: nil) - pipelines_scope = ci_ref.pipelines.artifacts_locked - pipelines_scope = pipelines_scope.before_pipeline(before_pipeline) if before_pipeline total_new_entries = 0 - pipelines_scope.each_batch(of: BATCH_SIZE) do |batch| + pipelines_scope(ci_ref, before_pipeline).each_batch(of: BATCH_SIZE) do |batch| pipeline_ids = batch.pluck(:id) # rubocop: disable CodeReuse/ActiveRecord total_added = Ci::UnlockPipelineRequest.enqueue(pipeline_ids) total_new_entries += total_added @@ -27,6 +26,34 @@ module Ci total_new_entries: total_new_entries ) end + + private + + def pipelines_scope(ci_ref, before_pipeline) + scope = ci_ref.pipelines.artifacts_locked + + if before_pipeline + # We use `same_family_pipeline_ids.map(&:id)` to force run the query and + # specifically pass the array of IDs to the NOT IN condition. If not, we would + # end up running the subquery for same_family_pipeline_ids on each batch instead. + excluded_ids = before_pipeline.same_family_pipeline_ids.map(&:id) + scope = scope.created_before_id(before_pipeline.id) + + # When unlocking previous pipelines, we still want to keep the + # last successful CI source pipeline locked. + # If before_pipeline is not provided, like in the case of deleting a ref, + # we want to unlock all pipelines instead. + ci_ref.last_successful_ci_source_pipeline.try do |pipeline| + excluded_ids.concat(pipeline.same_family_pipeline_ids.map(&:id)) + end + + # We add a limit to the excluded IDs just to be safe and avoid any + # arity issues with the NOT IN query. + scope = scope.where.not(id: excluded_ids.take(EXCLUDED_IDS_LIMIT)) # rubocop: disable CodeReuse/ActiveRecord + end + + scope + end end end end |