Commit e13ab34a authored by Tetiana Chupryna's avatar Tetiana Chupryna

Fix N+1 in checking for registry tags

In namespace#any_project_has_container_registry_tags?
we preload container_repositories so we don't need to
query registries for each project.
Fix for
https://gitlab.com/gitlab-org/gitlab/-/issues/21042

Changelog: performance
parent dca61a20
......@@ -198,7 +198,7 @@ class Namespace < ApplicationRecord
end
def any_project_has_container_registry_tags?
all_projects.any?(&:has_container_registry_tags?)
all_projects.includes(:container_repositories).any?(&:has_container_registry_tags?)
end
def first_project_with_container_registry_tags
......
---
title: Fix N+1 queries in namespace#any_project_has_container_registry_tags?
merge_request: 59916
author:
type: performance
......@@ -224,6 +224,47 @@ RSpec.describe Namespace do
it { expect(namespace.human_name).to eq(namespace.owner_name) }
end
describe '#any_project_has_container_registry_tags?' do
subject { namespace.any_project_has_container_registry_tags? }
let!(:project_without_registry) { create(:project, namespace: namespace) }
context 'without tags' do
it { is_expected.to be_falsey }
end
context 'with tags' do
before do
repositories = create_list(:container_repository, 3)
create(:project, namespace: namespace, container_repositories: repositories)
stub_container_registry_config(enabled: true)
stub_container_registry_tags(repository: :any, tags: ['tag'])
end
it 'finds tags' do
allow_next_found_instance_of(ContainerRepository) do |repository|
allow(repository).to receive(:has_tags?).and_return(true)
end
is_expected.to be_truthy
end
it 'does not cause N+1 query' do
allow_next_found_instance_of(ContainerRepository) do |repository|
allow(repository).to receive(:has_tags?).and_return(false)
end
control_count = ActiveRecord::QueryRecorder.new { namespace.any_project_has_container_registry_tags? }.count
other_repositories = create_list(:container_repository, 2)
create(:project, namespace: namespace, container_repositories: other_repositories)
expect { namespace.any_project_has_container_registry_tags? }.not_to exceed_query_limit(control_count)
end
end
end
describe '#first_project_with_container_registry_tags' do
let(:container_repository) { create(:container_repository) }
let!(:project) { create(:project, namespace: namespace, container_repositories: [container_repository]) }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment