Plugins: each plugin decision costs two queries, so a company page spends 21 of its 69 on policy #1112
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
performance
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
Postulo/postulo#1112
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What exists today
src/postulo/plugins/policy.py:312-318decide()memoises one answer per (plugin, person) for the request, keyed by the record stamp (_answers(),:300). But each first answer in_decide()(:321) runs its ownPluginPolicy.objects.filter(plugin=plugin_name).filter(<person or default>)(:345) and, when no administrator row for the person settles it,access_for()(:157, the query at:169, called at:360), which is a second query onPluginAccessjoined to the person's groups. Parents and needs (_unmet_needs) calldecide()for further plugins, each again two queries.Measured with
CaptureQueriesContexton the second GET ofjobs:company_detailfor a user with one company, underpostulo.config.settings.test(probeaudit/m_scripts/test_probe_queries.py, run as a single file): 69 queries, of whichplugins_pluginpolicy11 andplugins_pluginaccess10. The count does not grow with the person's data, sotests/test_query_budget.pydoes not catch it; it grows with the number of plugins and modules installed.What would change
On the first decision of a request, read every
PluginPolicyrow for the person and the instance default (person_id = pk OR person_id IS NULL), and everyPluginAccessrow for the person or their groups, in two queries, and keep them in the samememo.decisionsholder as the answers, under the same stamp._decide()andaccess_for()then read from those dicts. The rules stay exactly as written (person over group, most permissive group per right, administrator row over access list); only where the rows come from changes. The admin views that callaccess_for()directly (:197) can keep the single-plugin query.A budget test beside
tests/test_query_budget.pythat the company page and the dashboard make at most N policy queries whatever the number of plugins registered guards it.What it saves or protects
medium: 21 of 69 queries on a company's page (measured), down to 2, on every page that asks what is switched on
Accessibility
none
Decisions
Found by the efficiency and reliability audit of 2026-10-30 (finding Q1; index postulo/postulo#1108). Checked against
mainatdaee30b15(2026-10-30).