Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
d66d74a7
Commit
d66d74a7
authored
Aug 15, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
ad3ee493
8c8824d4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
74 additions
and
10 deletions
+74
-10
changelogs/unreleased/sh-fix-discussions-api-perf.yml
changelogs/unreleased/sh-fix-discussions-api-perf.yml
+5
-0
lib/api/discussions.rb
lib/api/discussions.rb
+16
-10
spec/requests/api/discussions_spec.rb
spec/requests/api/discussions_spec.rb
+53
-0
No files found.
changelogs/unreleased/sh-fix-discussions-api-perf.yml
0 → 100644
View file @
d66d74a7
---
title
:
Eliminate many Gitaly calls in discussions API
merge_request
:
31834
author
:
type
:
performance
lib/api/discussions.rb
View file @
d66d74a7
...
...
@@ -4,6 +4,7 @@ module API
class
Discussions
<
Grape
::
API
include
PaginationParams
helpers
::
API
::
Helpers
::
NotesHelpers
helpers
::
RendersNotes
before
{
authenticate!
}
...
...
@@ -23,21 +24,15 @@ module API
requires
:noteable_id
,
types:
[
Integer
,
String
],
desc:
'The ID of the noteable'
use
:pagination
end
# rubocop: disable CodeReuse/ActiveRecord
get
":id/
#{
noteables_path
}
/:noteable_id/discussions"
do
noteable
=
find_noteable
(
parent_type
,
params
[
:id
],
noteable_type
,
params
[
:noteable_id
])
notes
=
noteable
.
notes
.
inc_relations_for_view
.
includes
(
:noteable
)
.
fresh
notes
=
notes
.
reject
{
|
n
|
n
.
cross_reference_not_visible_for?
(
current_user
)
}
notes
=
readable_discussion_notes
(
noteable
)
discussions
=
Kaminari
.
paginate_array
(
Discussion
.
build_collection
(
notes
,
noteable
))
present
paginate
(
discussions
),
with:
Entities
::
Discussion
end
# rubocop: enable CodeReuse/ActiveRecord
desc
"Get a single
#{
noteable_type
.
to_s
.
downcase
}
discussion"
do
success
Entities
::
Discussion
...
...
@@ -226,13 +221,24 @@ module API
helpers
do
# rubocop: disable CodeReuse/ActiveRecord
def
readable_discussion_notes
(
noteable
,
discussion_id
)
def
readable_discussion_notes
(
noteable
,
discussion_id
=
nil
)
notes
=
noteable
.
notes
.
where
(
discussion_id:
discussion_id
)
notes
=
notes
.
where
(
discussion_id:
discussion_id
)
if
discussion_id
notes
=
notes
.
inc_relations_for_view
.
includes
(
:noteable
)
.
fresh
# Without RendersActions#prepare_notes_for_rendering,
# Note#cross_reference_not_visible_for? will attempt to render
# Markdown references mentioned in the note to see whether they
# should be redacted. For notes that reference a commit, this
# would also incur a Gitaly call to verify the commit exists.
#
# With prepare_notes_for_rendering, we can avoid Gitaly calls
# because notes are redacted if they point to projects that
# cannot be accessed by the user.
notes
=
prepare_notes_for_rendering
(
notes
)
notes
.
reject
{
|
n
|
n
.
cross_reference_not_visible_for?
(
current_user
)
}
end
# rubocop: enable CodeReuse/ActiveRecord
...
...
spec/requests/api/discussions_spec.rb
View file @
d66d74a7
...
...
@@ -9,6 +9,59 @@ describe API::Discussions do
project
.
add_developer
(
user
)
end
context
'with cross-reference system notes'
,
:request_store
do
let
(
:merge_request
)
{
create
(
:merge_request
)
}
let
(
:project
)
{
merge_request
.
project
}
let
(
:new_merge_request
)
{
create
(
:merge_request
)
}
let
(
:commit
)
{
new_merge_request
.
project
.
commit
}
let!
(
:note
)
{
create
(
:system_note
,
noteable:
merge_request
,
project:
project
,
note:
cross_reference
)
}
let!
(
:note_metadata
)
{
create
(
:system_note_metadata
,
note:
note
,
action:
'cross_reference'
)
}
let
(
:cross_reference
)
{
"test commit
#{
commit
.
to_reference
(
project
)
}
"
}
let
(
:url
)
{
"/projects/
#{
project
.
id
}
/merge_requests/
#{
merge_request
.
iid
}
/discussions"
}
before
do
project
.
add_developer
(
user
)
new_merge_request
.
project
.
add_developer
(
user
)
end
it
'returns only the note that the user should see'
do
hidden_merge_request
=
create
(
:merge_request
)
new_cross_reference
=
"test commit
#{
hidden_merge_request
.
project
.
commit
}
"
new_note
=
create
(
:system_note
,
noteable:
merge_request
,
project:
project
,
note:
new_cross_reference
)
create
(
:system_note_metadata
,
note:
new_note
,
action:
'cross_reference'
)
get
api
(
url
,
user
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
expect
(
json_response
.
count
).
to
eq
(
1
)
expect
(
json_response
.
first
[
'notes'
].
count
).
to
eq
(
1
)
parsed_note
=
json_response
.
first
[
'notes'
].
first
expect
(
parsed_note
[
'id'
]).
to
eq
(
note
.
id
)
expect
(
parsed_note
[
'body'
]).
to
eq
(
cross_reference
)
expect
(
parsed_note
[
'system'
]).
to
be
true
end
it
'avoids Git calls and N+1 SQL queries'
do
expect_any_instance_of
(
Repository
).
not_to
receive
(
:find_commit
).
with
(
commit
.
id
)
control
=
ActiveRecord
::
QueryRecorder
.
new
do
get
api
(
url
,
user
)
end
expect
(
response
).
to
have_gitlab_http_status
(
200
)
RequestStore
.
clear!
new_note
=
create
(
:system_note
,
noteable:
merge_request
,
project:
project
,
note:
cross_reference
)
create
(
:system_note_metadata
,
note:
new_note
,
action:
'cross_reference'
)
RequestStore
.
clear!
expect
{
get
api
(
url
,
user
)
}.
not_to
exceed_query_limit
(
control
)
expect
(
response
).
to
have_gitlab_http_status
(
200
)
end
end
context
'when noteable is an Issue'
do
let!
(
:issue
)
{
create
(
:issue
,
project:
project
,
author:
user
)
}
let!
(
:issue_note
)
{
create
(
:discussion_note_on_issue
,
noteable:
issue
,
project:
project
,
author:
user
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment