Preload policy data for batch permission checks

What does this MR do and why?

Checking whether a user can read a list of issues gets slower with every issue in the list. Each check loads that issue's project, group, membership and work item type on its own, so 96 issues cost over 400 database queries. This affects Markdown references, linked items, epic issues and the issues API.

This MR lets a policy load what its checks need for the whole list in one go, and uses that for issues. The results don't change, only how the data is loaded. A single issue skips the extra loading, since it has nothing to share.

Local measurements, 96 issues across 12 projects in 4 groups:

Queries Time
Before 423 1,148 ms
After 44 180 ms

Small lists of 2–4 issues from one project run a few more queries than before (27 instead of 23). From about 3 projects or 9 issues the new path is faster.

The new loading is behind the batch_permission_check_preloads flag, so it can be turned off quickly if a permission check goes wrong. Its cost is counted in the existing authz_* log fields, so the rollout can compare them with the flag on and off.

Other *_readable_by_user methods, such as merge requests and pipelines, can move to the same approach in follow-ups.

References

Screenshots or screen recordings

Not applicable: no UI changes.

How to set up and validate locally

Nothing to check by hand. The results are the same as before, and the specs compare them with checking each issue on its own and limit the query count.

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.

Edited by Ian Anderson

Merge request reports

Loading
Loading