Reduce work items list query complexity for anonymous users
What does this MR do and why?
This MR brings the work items list query (specifically getWorkItemsFullEE) under the unauthenticated complexity limit, this is a follow-up of !253748 (merged).
Problem
We have following query complexity limits in place for various user types:
root- 300- Regular users - 250
- Anonymous users - 200
With work_item_features_field enabled globally, if an anonymous user would visit a work items list, it would open fine as long as page size is 20 or 50, but the moment they go to page size 100, the getWorkItemsFullEE query would fail as the total complexity of that query became 240, thus breaching the limit of 200 for anonymous users. The listing page still loaded and showed work items, but it missed the additional metadata that is fetched via getWorkItemsFullEE and user would see a failure banner on the page. For logged in users, this never became an issue as query stayed under 250.
Fix
Work Items list currently fires two queries in parallel; getWorkItemsSlimEE and getWorkItemsFullEE, and we were duplicating the fields in full query, even the ones that we already fetched in slim query, in this MR, we've removed those duplicates, resulting in much smaller complexity. And this is fine because Apollo would merge the results when queries are complete so no fields are lost.
Implementation notes
- Deduplicated
get_work_items_full.query.graphql(CE and EE) so it no longer includes fields likeiid,author,createdAt, andwebUrlthatget_work_items_slim.query.graphqlalready fetches; this is the change that brings the query under the complexity cap. - Updated
combineWorkItemListsinapp/assets/javascripts/work_items/utils.jsto spread the slim item response on top of full item. - Added the missing
@skip(if: $useWorkItemFeatures)directive to the EE slim query'swidgets(onlyTypes: [LABELS])selection, matching CE, since without it EE was loading labels twice on bothwidgets[]andfeaturessub-trees. - Fixed three MSW test suites that assumed slim's fields were a subset of full's:
views_spec.jsandpreferences_spec.jsnow look up work items bytitlein the slim fixture instead of full, and we added a realget_work_items_slim_closedfixture instead of aliasing the full closed one. - Extended
ee/spec/graphql/all_queries_spec.rbto assert the unauthenticated 200-point cap at page sizes 20, 50 and 100, since page size 100 previously only checked the authenticated 250 cap, which is how this complexity breach reached production.- The
complexity_overridesentries of 360 for both list queries were removed.
- The
Here are updated numbers for complexity
| Page size | full before |
full after |
slim before |
slim after |
|---|---|---|---|---|
| 20 | 145 | 111 | 68 | 66 |
| 50 | 180 | 138 | 84 | 82 |
| 100 | 240 | 183 | 141 | 109 |
183 against a 200 cap for anonymous users
References
- #587972
- #589609 (closed)
- Follow-up to !253748 (merged)
Screenshots or screen recordings
Group work items list at ?first_page_size=100, logged out, work_item_features_field enabled.
| Before | After |
|---|---|
How to set up and validate locally
- Enable the flag with
Feature.enable(:work_item_features_field). - Open a group work items list with
?first_page_size=100in a logged-out session, for examplehttp://gdk.test:3000/groups/gitlab-org/-/work_items?first_page_size=100. - Confirm the list renders with no error banner and that
getWorkItemsFullEEreturns no complexity error. - Confirm the cards still show assignees, labels, milestone, iteration, dates, weight, health status, status, comment counts and upvotes.
- Repeat signed in as a regular user and as an admin.
- Repeat with the flag disabled to check the
widgetspath still renders the same cards.
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.