Our GraphQL authorizations are too eager
Summary
Work on !32113 (merged) has discovered that our GraphQL authorizations are too eager, and this defeats the batching optimizations we have worked very hard to create and test.
Specifically, the following query will issue one request for each project, rather than a single query:
This is caused by eager evaluation (calls to #sync
) in type authorizations.
Steps to reproduce
See the pending test at: !32113 (2004662e)
I have confirmed that this test passes when the authorizations on LabelType
are commented out.
Example Query
query {
project(fullPath: "gitlab-org/gitlab") {
mr_a: mergeRequest(iid: 123) { title }
mr_b: mergeRequest(iid: 124) { title }
}
}
This should issue a single query for the merge requests, but it will issue two.
What is the current bug behavior?
One query is issued for each item, so we have N + 1
performance.
What is the expected correct behavior?
They should be batched.
Output of checks
This bug happens on GitLab.com
Possible fixes
At AuthorizeFieldService line 95
instead of calling sync directly, we should be operating in an #GitlabSchema#after_lazy
context.
This is a private API, but this will ensure things are evaluated in the correct order
Anyone who reads our code and sees the extensive use of batch-loading would assume that the advice given in https://graphql-ruby.org/schema/lazy_execution.html would hold for us, but it does not, and the example given in the guide would not benefit from batching for us.
/cc @digitalmoksha