Skip to content

perf: cache parsed permissions per request#1167

Draft
aiolibsbot wants to merge 1 commit into
aio-libs:masterfrom
aiolibsbot:koan/cache-parsed-permissions
Draft

perf: cache parsed permissions per request#1167
aiolibsbot wants to merge 1 commit into
aio-libs:masterfrom
aiolibsbot:koan/cache-parsed-permissions

Conversation

@aiolibsbot

@aiolibsbot aiolibsbot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

What

Parse each request's permission strings once instead of on every permission check.

Why

AdminAuthorizationPolicy.permits() called permissions_as_dict() on every
invocation. That helper splits each permission string on | / = and runs
json.loads on every filter value. Because permits() runs roughly
O(records * fields) times per list request (once per record, and again per
field for field-level checks), the same permission set was re-parsed dozens of
times for a single response — even though it is identical for the whole request.

The request already cached the raw collection under
aiohttpadmin_permissions, and a comment in abc.py claimed the parsed form
was cached — but it wasn't; every reader re-parsed it.

How

Cache the parsed dict (not the raw collection) under the existing
aiohttpadmin_permissions request key, so parsing happens exactly once per
request. The advanced-permission filter path in backends/abc.py now reads the
cached dict directly instead of re-parsing. No behavioral change — the cached
key is internal (no docs/tests reference the raw form).

Testing

pytest tests/ — 97 passed, 1 xfailed. The one unrelated pre-existing failure
(test_views.py::test_admin_view, tracked in #934) fails identically on the
base branch. The permission-filter and field-level permission tests exercise
both the permits() path and the abc.py filter path end-to-end.


Quality Report

Changes: 2 files changed, 12 insertions(+), 8 deletions(-)

Code scan: clean

Tests: failed (command not found)

Branch hygiene: clean

Generated by Kōan

permits() ran permissions_as_dict() on every call, re-splitting each
permission string and json.loads-ing every filter value. Since permits()
is invoked O(records * fields) times per list request, this parsing was
repeated for every record/field even though the underlying permissions
are identical for the whole request.

Cache the parsed dict (not the raw collection) under the existing
aiohttpadmin_permissions request key so the strings are parsed once.
Update the list-filter path in abc.py to read the cached dict directly.
@codecov

codecov Bot commented Jul 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.63%. Comparing base (2448fd1) to head (74905f9).
⚠️ Report is 168 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1167      +/-   ##
==========================================
+ Coverage   95.56%   95.63%   +0.06%     
==========================================
  Files          21       21              
  Lines        2954     2955       +1     
  Branches      193      200       +7     
==========================================
+ Hits         2823     2826       +3     
+ Misses        105      103       -2     
  Partials       26       26              
Flag Coverage Δ
integration 81.24% <100.00%> (+0.28%) ⬆️
js 83.89% <ø> (ø)
unit 97.50% <100.00%> (+0.08%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant