eschutho opened a new pull request, #44402:
URL: https://github.com/apache/superset/pull/44402

   ### SUMMARY
   
   **The problem.** When a chart has annotation layers, Superset was saving a 
separate copy of that chart's cached data for *every user* who viewed it — even 
when all of them would see exactly the same result. A single chart could turn 
into hundreds of identical copies in the cache, and since each copy can be tens 
of megabytes, this wasted a large amount of cache memory for no benefit.
   
   **Why it happened.** Annotations (the extra markers/notes drawn on a chart) 
are loaded using the viewer's own permissions, and they get stored in the 
*same* cache entry as the chart's data. To make sure a user could never be 
served annotation data they weren't allowed to see, the code mixed the viewer's 
user ID into the cache key. That was safe, but too blunt: because the user ID 
is part of the key, every user got their own copy — including users who would 
see identical data.
   
   **The fix.** Instead of keying the cache on *who the user is*, we now key it 
on *what the user is allowed to see* (their access scope). Users with the same 
access share one cache entry; users with different access — or no access — 
never share one. This keeps the exact same safety guarantee (nobody is served 
annotation data they shouldn't see) while letting identical results be reused 
instead of duplicated. Concretely:
   
   - **Built-in ("native") annotation layers** show global annotation records 
that are gated only by the "can read annotations" permission, so the key now 
includes just that permission flag.
   - **Chart-based annotation layers** (annotations pulled from another chart) 
run a query against that chart's data source. The key now includes (a) whether 
the user can access that data source — previously this access check only ran 
when the data was missing from the cache, not when it was served from the cache 
— and (b) that other chart's own cache key, which already accounts for the data 
source version, row-level security (RLS) rules, and any per-user RLS logic.
   
   So users with genuinely different access still get their own cache entries; 
users with the same access now share one.
   
   **Second, related change: size cap.** Superset can already skip caching 
values that are too large (`DATA_CACHE_MAX_VALUE_SIZE`), but a few code paths 
wrote to the DATA cache directly and skipped that check: the SQL executor's 
result cache, and two datasource endpoints (filter-dropdown values, and 
metrics/dimensions). This PR sends those through the same size check so 
oversized values can't slip in there either. It does nothing when the cap is 
turned off (the default), so it adds no overhead by default.
   
   **Expiry (TTL) note.** Every cache write touched here already sets an expiry 
time. The special `timeout=0` ("never expire") value is an intentional, 
documented feature and is left unchanged.
   
   ### BEFORE/AFTER SCREENSHOTS OR ANIMATED GIF
   
   N/A — this is a caching / cache-key change with no UI surface.
   
   ### TESTING INSTRUCTIONS
   
   Unit tests (added/updated, verified to fail before the fix and pass after):
   
   ```
   pytest tests/unit_tests/common/test_query_context_processor.py -k 
annotation_cache_key
   pytest tests/unit_tests/utils/cache_test.py
   ```
   
   - The annotation cache-key tests check that identical annotation-layer 
results are shared across users with the same access, and still stay separate 
when the annotation-read permission, datasource access, or RLS genuinely 
differs.
   - The cache-util tests check that the shared size guard skips oversized 
values (and counts `skip_cache_value_too_large`), and does nothing when the cap 
is disabled.
   
   Manual check: open a chart with annotation layers as two users who share the 
same role and RLS, and confirm only one cached data entry is created (not one 
per user). Then view it as a user whose access or RLS differs, and confirm they 
get their own separate entry.
   
   ### ADDITIONAL INFORMATION
   - [ ] Has associated issue:
   - [ ] Required feature flags:
   - [ ] Changes UI
   - [ ] Includes DB Migration (follow approval process in 
[SIP-59](https://github.com/apache/superset/issues/13351))
   - [ ] Introduces new feature or API
   - [ ] Removes existing feature or API
   - [x] Bug fix (non-breaking change which fixes an issue)
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to