Commit d1043778 authored by Eugenia Grieff's avatar Eugenia Grieff Committed by Markus Koller

Preload parent in group epics query

- Use Lookahead to preload the field parent
when querying group epics using GraphQL
parent 8537faa8
......@@ -67,6 +67,12 @@ module Resolvers
[:group]
end
def preloads
{
parent: [:parent]
}
end
def find_epics(args)
apply_lookahead(EpicsFinder.new(context[:current_user], args).execute)
end
......
......@@ -32,8 +32,7 @@ module Types
field :group, GroupType, null: false,
description: 'Group to which the epic belongs'
field :parent, EpicType, null: true,
description: 'Parent epic of the epic',
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(Epic, obj.parent_id).find }
description: 'Parent epic of the epic'
field :author, Types::UserType, null: false,
description: 'Author of the epic',
resolve: -> (obj, _args, _ctx) { Gitlab::Graphql::Loaders::BatchModelLoader.new(User, obj.author_id).find }
......
---
title: Preload parent in GraphQL epics queries using Lookahead
merge_request: 43323
author:
type: performance
......@@ -17,25 +17,27 @@ RSpec.describe 'Epics through GroupQuery' do
# similar to GET /groups/:id/epics
describe 'Get list of epics from a group' do
let(:query) do
epic_node = <<~NODE
edges {
node {
id
iid
title
upvotes
downvotes
userPermissions {
adminEpic
let(:epic_node) do
<<~NODE
edges {
node {
id
iid
title
upvotes
downvotes
userPermissions {
adminEpic
}
}
}
}
NODE
end
def query(params = {})
graphql_query_for("group", { "fullPath" => group.full_path },
['epicsEnabled',
query_graphql_field("epics", {}, epic_node)]
query_graphql_field("epics", params, epic_node)]
)
end
......@@ -105,6 +107,42 @@ RSpec.describe 'Epics through GroupQuery' do
end
end
end
context 'query performance' do
let!(:child_epic) { create(:epic, group: group, parent: epic2) }
let(:epic_node) do
<<~NODE
edges {
node {
parent {
id
}
}
}
NODE
end
before do
group.reload
post_graphql(query, current_user: user)
end
it 'avoids n+1 queries when loading parent field' do
control_count = ActiveRecord::QueryRecorder.new(skip_cached: false) do
post_graphql(query, current_user: user)
end.count
epics_with_parent = create_list(:epic, 3, group: group) do |epic|
epic.update(parent: create(:epic, group: group))
end
group.reload
# Added +1 to control_count due to an existing N+1 with licenses
expect do
post_graphql(query({ iids: epics_with_parent.pluck(:iid) }), current_user: user)
end.not_to exceed_all_query_limit(control_count + 1)
end
end
end
context 'when error requests' 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