Commit ba7c501f authored by Stan Hu's avatar Stan Hu

Fix Gitaly N+1 calls with listing issues/MRs via API

In GitLab 9.0,
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/9661 removed the
`subscribed` flag from the API when the user requested a list of issues
or merge requests since calculating this value triggers extensive
Markdown processing.

In GitLab 12.0 via a4fbf39e, we accidentally reintroduced this
performance regression by changing `IssueBasic` to `Issue` in
`entities.rb`. This showed up as a Gitaly N+1 issue since the Markdown
processing would attempt to extract a commit if it detected a regex that
matched a commit.

We restore the prior behavior by once again removing the `subscribed`
flag for the bulk list of issues and merge requests and add a test to
ensure they aren't reintroduced.

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/66202
parent 1068483f
---
title: Fix Gitaly N+1 calls with listing issues/MRs via API
merge_request: 31938
author:
type: performance
......@@ -136,7 +136,6 @@ Example response:
"award_emoji":"http://example.com/api/v4/projects/1/issues/76/award_emoji",
"project":"http://example.com/api/v4/projects/1"
},
"subscribed": false,
"task_completion_status":{
"count":0,
"completed_count":0
......@@ -441,7 +440,6 @@ Example response:
"award_emoji":"http://example.com/api/v4/projects/4/issues/41/award_emoji",
"project":"http://example.com/api/v4/projects/4"
},
"subscribed": false,
"task_completion_status":{
"count":0,
"completed_count":0
......
......@@ -645,7 +645,10 @@ module API
end
end
expose :subscribed do |issue, options|
# Calculating the value of subscribed field triggers Markdown
# processing. We can't do that for multiple issues / merge
# requests in a single API request.
expose :subscribed, if: -> (_, options) { options.fetch(:include_subscribed, true) } do |issue, options|
issue.subscribed?(options[:current_user], options[:project] || issue.project)
end
end
......
......@@ -96,7 +96,8 @@ module API
with: Entities::Issue,
with_labels_details: declared_params[:with_labels_details],
current_user: current_user,
issuable_metadata: issuable_meta_data(issues, 'Issue', current_user)
issuable_metadata: issuable_meta_data(issues, 'Issue', current_user),
include_subscribed: false
}
present issues, options
......@@ -122,7 +123,8 @@ module API
with: Entities::Issue,
with_labels_details: declared_params[:with_labels_details],
current_user: current_user,
issuable_metadata: issuable_meta_data(issues, 'Issue', current_user)
issuable_metadata: issuable_meta_data(issues, 'Issue', current_user),
include_subscribed: false
}
present issues, options
......
......@@ -342,6 +342,14 @@ describe API::Issues do
group_project.add_reporter(user)
end
it 'exposes known attributes' do
get api(base_url, admin)
expect(response).to have_gitlab_http_status(200)
expect(json_response.last.keys).to include(*%w(id iid project_id title description))
expect(json_response.last).not_to have_key('subscribed')
end
it 'returns all group issues (including opened and closed)' do
get api(base_url, admin)
......
......@@ -575,6 +575,7 @@ describe API::Issues do
expect(json_response['assignee']).to be_a Hash
expect(json_response['author']).to be_a Hash
expect(json_response['confidential']).to be_falsy
expect(json_response['subscribed']).to be_truthy
end
it 'exposes the closed_at attribute' do
......
......@@ -216,6 +216,10 @@ describe API::Issues do
expect_paginated_array_response([issue.id, closed_issue.id])
expect(json_response.first['title']).to eq(issue.title)
expect(json_response.last).to have_key('web_url')
# Calculating the value of subscribed field triggers Markdown
# processing. We can't do that for multiple issues / merge
# requests in a single API request.
expect(json_response.last).not_to have_key('subscribed')
end
it 'returns an array of closed issues' do
......
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