Cap the project releases Atom feed and JSON list
What does this MR do and why?
Context
The project releases Atom feed (/-/releases.atom) and JSON list (/-/releases.json) load every release of the project, with evidences, milestones and links that neither format reads. Their cost grows with the number of releases, and the Atom feed also looks up a commit and renders Markdown for each one. The figures and the agreed approach are in https://gitlab.com/gitlab-org/gitlab/-/work_items/638260#note_4198617884.
This MR
- The Atom feed lists only the newest 100 releases and preloads only each release's author and project.
- The JSON list returns only the newest 1,000 releases, with no preloads. Its UI callers, the Release filters on the merge request and work item lists, use only each release's tag.
- Both keep the newest-first order, and each cap has its own feature flag, so one can be rolled back without the other. The Releases API still lists every release, and the docs now say so under "Track releases with an RSS feed".
- The Changelog entry comes with each flag-removal MR.
This keeps the cost of both requests bounded however many releases a project has.
Feature Flag: project_releases_atom_limit
Feature Flag: project_releases_json_limit
References
- https://gitlab.com/gitlab-org/gitlab/-/work_items/638260+
- https://gitlab.com/gitlab-org/gitlab/-/work_items/639355+
- https://gitlab.com/gitlab-org/gitlab/-/work_items/639356+
Database queries
See MR comments.
How to set up and validate locally
- In a Rails console, give a project more releases than the caps, using smaller caps so it stays quick:
project = Project.find_by_full_path('<your-project>') user = project.first_owner 5.times { |i| Release.create!(project: project, author: user, tag: "v0.0.#{i}", name: "v0.0.#{i}", sha: project.commit.id, released_at: i.days.ago) } - Open
http://gdk.test:3000/<your-project>/-/releases.atomandhttp://gdk.test:3000/<your-project>/-/releases.json. Both list every release, newest first. - In
app/controllers/projects/releases_controller.rb, setATOM_RELEASES_LIMIT = 2andJSON_RELEASES_LIMIT = 3. In a Rails console, runFeature.enable(:project_releases_atom_limit)andFeature.enable(:project_releases_json_limit), and wait a minute. - Reload both URLs. The feed lists the newest 2 releases and the JSON list the newest 3, and
log/development.logshowsORDER BY "releases"."released_at" DESC LIMIT 2for the feed andLIMIT 3for the JSON list, and norelease_linksqueries for either.
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.