[bug]: Workspace labels/estimates API returns stale data for up to 2 hours after label rename/delete or estimate changes (per-user cache not invalidated)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 45/100
Direzione di ricerca
Start with invalidate_cache and cache_response in apps/api/plane/utils/cache.py, then the write paths in app/views/issue/label.py, app/views/estimate/base.py and app/views/project/base.py. Ask maintainers first whether they want Option A (clear every user's key) or Option B (drop @cache_response), since the issue leaves that open. Done means that after a label or estimate write, a different user's GET on the workspace labels or estimates endpoint returns the new data.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Is there an existing issue for this?
- I have searched the existing issues
Current behavior
GET /api/workspaces/<slug>/labels/ and GET /api/workspaces/<slug>/estimates/ are cached separately for each user for 2 hours when DEBUG is off (the default in plane.settings.production). Several writes don't clear that cache, so these endpoints keep returning the old response until it expires.
Expected: after a label or estimate changes, the next request to these endpoints returns current data.
Actual: the response cached before the change is returned for up to 2 hours.
Confirmed affected operations:
| Operation | Endpoint | Result |
|---|---|---|
| Rename a label | PATCH /api/workspaces/<slug>/projects/<project_id>/issue-labels/<id>/ |
workspace labels still show the old name |
| Delete a label | DELETE …/issue-labels/<id>/ |
deleted label still returned |
| Update an estimate | PATCH /api/workspaces/<slug>/projects/<project_id>/estimates/<id>/ |
old point values still returned |
| Delete an estimate | DELETE …/estimates/<id>/ |
deleted estimate still returned |
| Enable an estimate on a project | PATCH /api/workspaces/<slug>/projects/<project_id>/ with {"estimate": "<id>"} |
workspace estimates still return the pre-change response (empty in the test) |
Two operations worked correctly in the same test:
- Creating a label clears the cache. This was fixed in #6587.
- Creating an estimate on its own changes nothing visible. The workspace endpoint only returns estimates attached to a project, so the response is the same either way.
Why it happens
cache_responseinapps/api/plane/utils/cache.pydefaults touser=True.WorkspaceLabelsEndpoint.get(app/views/workspace/label.py) andWorkspaceEstimatesEndpoint.get(app/views/workspace/estimate.py) therefore save under per-user keys, e.g./api/workspaces/<slug>/labels/:<user_id>.LabelViewSet.partial_updateandLabelViewSet.destroy(app/views/issue/label.py), andBulkEstimatePointEndpoint.partial_updateanddestroy(app/views/estimate/base.py), callinvalidate_cache(..., url_params=True, user=False)withoutmultiple=True.invalidate_cache_directlythen deletes/api/workspaces/<slug>/labels/exactly, a key that is never written.LabelViewSet.createpassesmultiple=True, which deletes by pattern (*<key>*) and clears every user's entry. #6587 fixed label create this way.ProjectViewSet.partial_update(app/views/project/base.py) has no cache clearing at all, so enabling an estimate on a project isn't reflected.
Steps to reproduce
I reproduced this against an isolated API built from preview @ 4605f0078f. It used plane.settings.production, DEBUG=False, Redis (Valkey) and Postgres, with real HTTP requests authenticated by session cookie. I did not test the web UI.
The cache is per user, so each check below must be made by a user whose cached response was stored before the write. To compare against the database, request the same URL with a dummy query string (e.g. ?x=1). That's a different cache key, so it returns current data.
Labels (one project admin):
- Create a label
alphain a project. GET /api/workspaces/<slug>/labels/returnsalpha, and the response is now cached for this user.PATCH /api/workspaces/<slug>/projects/<project_id>/issue-labels/<label_id>/with{"name": "beta"}returns 200.GET /api/workspaces/<slug>/labels/still returnsalpha, while?x=1returnsbeta.DELETEthe label, which returns 204.GET /api/workspaces/<slug>/labels/still returnsalpha, while?x=1returns[].
Enabling an estimate (user A, project admin; workspace has no estimates in use):
6. GET /api/workspaces/<slug>/estimates/ returns [], which is now cached for user A.
7. POST /api/workspaces/<slug>/projects/<project_id>/estimates/ creates an estimate with points 1, 2. GET …/estimates/ still returns [], and so does ?x=1, so nothing is stale yet.
8. PATCH /api/workspaces/<slug>/projects/<project_id>/ with {"estimate": "<estimate_id>"} returns 200.
9. GET /api/workspaces/<slug>/estimates/ still returns [] for user A, while ?x=1 returns the estimate with points 1, 2.
Updating and deleting an estimate (user B, project admin; writes done by user A):
10. After step 8, user B requests GET /api/workspaces/<slug>/estimates/ for the first time. It returns the estimate with points 1, 2, now cached for user B.
11. User A sends PATCH /api/workspaces/<slug>/projects/<project_id>/estimates/<estimate_id>/ with the point values changed to v10, v20, which returns 200. User B's GET …/estimates/ still returns 1, 2, while ?x=1 returns v10, v20.
12. User A sends DELETE …/estimates/<estimate_id>/, which returns 204. User B's GET …/estimates/ still returns the estimate with points 1, 2, while ?x=1 returns [].
Checked at the end of the run, the cached label key had a Redis TTL of about 7,185 s, consistent with the 2-hour timeout.
Not tested: other writes that may also leave these responses stale. I haven't verified them:
- v1 API label writes
- the estimate-point endpoints (
…/estimates/<id>/estimate-points/) - project membership changes, since the label/estimate list depends on which projects the user belongs to
Question for maintainers
Which approach would you prefer?
- Option A: Fix cache clearing. Change the affected calls so they clear every user's cached copy, as #6587 did for label create, and add clearing to project estimate selection. Other write paths that change these responses (listed above) would need auditing, and possibly the same treatment.
- Option B: Remove caching from these two endpoints. Drop
@cache_responsefromWorkspaceLabelsEndpointandWorkspaceEstimatesEndpoint, as #7714 did forWorkspaceStatesEndpoint. That avoids staleness from any write path, including ones that don't clear the cache explicitly. The trade-off is that every request would hit the database, which may matter for performance on larger workspaces.
I'm happy to implement whichever approach you prefer and add regression tests.
Environment
Production
Browser
Other (reproduced at API level; UI not tested)
Edition
Community
Version
preview @ 4605f0078f (apps/api 1.4.2)
- Lingua principale
- TypeScript
- Stelle
- 61.1k
- Fork
- 6.1k
- Merge medio
- 1g 12h
- PR unite (30g)
- 80
Preparare l'ambiente
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di makeplane/plane
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
I maintainer di solito rispondono entro 1 giorno
-
[bug]: Email notifications show a broken avatar for users without a profile photoForse già presa @gurnoorpannu l’ha presa 5 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
makeplane/plane#10009 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
🐛 Bug: Calendar work items cannot be opened on mobileForse già presa @pennnnnnnnnn l’ha presa 7 giorni fa. Aperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
[bug]: First day of the week section not translated when Idioma is EspañolForse già presa @deepcfr l’ha presa 10 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
makeplane/plane#9967 · 2 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
[bug]: First day of the week section not translated when Idioma is EspañolForse già presa @Indira-kumar l’ha presa 8 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di makeplane/plane
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
radix-ui/primitives#4228 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
SignalK/freeboard-sk#1093 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno
-
[测试] 等待仓库加载后再记录多仓库排序基线Forse già presa @myot233 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
I maintainer di solito rispondono entro 1 giorno