Commit 44777e66 authored by Luke Duncalfe's avatar Luke Duncalfe

Fix N+1 issues in API v3/repos/{full-path}/events

https://gitlab.com/gitlab-org/gitlab/-/issues/321839
parent ecdb95a8
---
name: api_v3_repos_events_optimization
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54618
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/322059
milestone: '13.10'
type: development
group: group::ecosystem
default_enabled: false
......@@ -194,13 +194,19 @@ module API
# Self-hosted Jira (tested on 7.11.1) requests this endpoint right
# after fetching branches.
# rubocop: disable CodeReuse/ActiveRecord
get ':namespace/:project/events' do
user_project = find_project_with_access(params)
merge_requests = authorized_merge_requests_for_project(user_project)
if Feature.enabled?(:api_v3_repos_events_optimization, user_project)
merge_requests = merge_requests.preload(:author, :assignees, :metrics, source_project: :namespace, target_project: :namespace)
end
present paginate(merge_requests), with: ::API::Github::Entities::PullRequestEvent
end
# rubocop: enable CodeReuse/ActiveRecord
params do
use :project_full_path
......
......@@ -149,6 +149,8 @@ RSpec.describe API::V3::Github do
end
describe 'GET events' do
include ProjectForksHelper
let(:group) { create(:group) }
let(:project) { create(:project, :empty_repo, path: 'project.with.dot', group: group) }
let(:events_path) { "/repos/#{group.path}/#{project.path}/events" }
......@@ -174,6 +176,34 @@ RSpec.describe API::V3::Github do
end
end
it 'avoids N+1 queries' do
create(:merge_request, source_project: project)
source_project = fork_project(project, nil, repository: true)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { jira_get v3_api(events_path, user) }.count
create_list(:merge_request, 2, :unique_branches, source_project: source_project, target_project: project)
expect { jira_get v3_api(events_path, user) }.not_to exceed_all_query_limit(control_count)
end
context 'with `api_v3_repos_events_optimization` feature flag disabled' do
before do
stub_feature_flags(api_v3_repos_events_optimization: false)
end
it 'falls back to less optimal query performance' do
create(:merge_request, source_project: project)
source_project = fork_project(project, nil, repository: true)
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) { jira_get v3_api(events_path, user) }.count
create_list(:merge_request, 2, :unique_branches, source_project: source_project, target_project: project)
expect { jira_get v3_api(events_path, user) }.to exceed_all_query_limit(control_count)
end
end
context 'if there are more merge requests' do
let!(:merge_request) { create(:merge_request, id: 10000, source_project: project, target_project: project, author: user) }
let!(:merge_request2) { create(:merge_request, id: 10001, source_project: project, source_branch: generate(:branch), target_project: project, author: user) }
......
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