[Fixes #14097] Label thesaurus is not reloaded on thesaurus changes#14098
[Fixes #14097] Label thesaurus is not reloaded on thesaurus changes#14098
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates GeoNode’s i18n caching logic so that changes to the labels-i18n Thesaurus reliably invalidate previously cached localized label data (and related i18n-derived caches) instead of continuing to serve stale values.
Changes:
- When the Thesaurus
datechanges, invalidate cached i18n data by clearing the in-memory cache rather than only invalidating the current(lang, data_key)lookup.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if cached_entry and cached_entry.date != thesaurus_date: | ||
| logger.info(f"Cache for {lang}:{data_key} needs to be recreated") | ||
| logger.info(f"Cache for {lang}:{data_key} dirty, clearing all caches") | ||
| self.lang_cache.clear() | ||
| return thesaurus_date, None |
There was a problem hiding this comment.
get_entry() now clears self.lang_cache under _lock, but set() and clear() mutate self.lang_cache without acquiring the same lock. This creates a real race where one thread can be in setdefault()/write while another thread clears the dict, leading to lost updates and inconsistent cache state. Consider guarding all lang_cache mutations (set(), clear(), force_check()) with _lock (or switching to a thread-safe strategy) so invalidation is atomic across readers/writers.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Applied in commit a2745f9. All lang_cache mutations (set(), clear(), force_check()) are now guarded with _lock. The DB query in set() is intentionally kept outside the lock to avoid holding it during I/O, with only the actual cache mutations inside the lock context.
| if cached_entry and cached_entry.date != thesaurus_date: | ||
| logger.info(f"Cache for {lang}:{data_key} needs to be recreated") | ||
| logger.info(f"Cache for {lang}:{data_key} dirty, clearing all caches") | ||
| self.lang_cache.clear() | ||
| return thesaurus_date, None |
There was a problem hiding this comment.
The new behavior invalidates the entire i18n cache when the Thesaurus date changes. Given this is a regression fix (and i18nCache is also used for other cached data like metadata schema), it would be good to add a unit test that reproduces the stale-cache scenario and asserts that previously cached values (e.g., schema and/or labels for multiple languages) are rebuilt after a Thesaurus update.
There was a problem hiding this comment.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Added in commit d6add25. The new test test_stale_cache_invalidated_on_thesaurus_update in geonode/metadata/tests/test_i18n.py:
- Warms up the cache with labels for both
enandit - Updates the label values in the DB and bumps the Thesaurus
date(simulating a real thesaurus update) - Forces a freshness check (bypassing
CHECK_INTERVAL) - Asserts that both language caches are rebuilt with the new values, not the stale ones
Agent-Logs-Url: https://github.com/GeoNode/geonode/sessions/26a81ebe-aef6-4850-b356-885f6bdce0dc Co-authored-by: etj <717359+etj@users.noreply.github.com>
|
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @Copilot on file. In order for us to review and merge your code, please contact the project maintainers to get yourself added. |
Agent-Logs-Url: https://github.com/GeoNode/geonode/sessions/cbf02dc8-5fb7-402a-9ab5-9f58f1a5378e Co-authored-by: etj <717359+etj@users.noreply.github.com>
|
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @Copilot on file. In order for us to review and merge your code, please contact the project maintainers to get yourself added. |
|
@copilot apply black formatting |
Agent-Logs-Url: https://github.com/GeoNode/geonode/sessions/73015399-e501-43f4-8387-7807b3257567 Co-authored-by: etj <717359+etj@users.noreply.github.com>
|
Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @Copilot on file. In order for us to review and merge your code, please contact the project maintainers to get yourself added. |
…format * commit 'f8e9fb4585129ad4e028ede61e55e468575207c2': (34 commits) Fix formatting Merge commit from fork [Fixes GeoNode#13939] Add support for non-spatial datasets in CSV format in GeoNode (GeoNode#13900) build(deps): bump cryptography from 46.0.5 to 46.0.7 (GeoNode#14116) Add resourcehandlerinfo creation management command (GeoNode#14118) build(deps): update jwcrypto requirement from >=1.5.6 to >=1.5.7 (GeoNode#14127) build(deps-dev): update pip requirement from >=19.1 to >=26.0.1 (GeoNode#14125) [Fixes GeoNode#14095] Upload thumbnails through the UI for the remote spatial datasets (GeoNode#14096) build(deps): bump python-calamine from 0.6.1 to 0.6.2 (GeoNode#14102) build(deps): bump django from 5.2.12 to 5.2.13 (GeoNode#14115) [Fixes GeoNode#14111] Fix Harvester lookup failure caused by trailing ? during the remote resource upload through the API (GeoNode#14112) updated folder for RTD [Fixes GeoNode#14097] Label thesaurus is not reloaded on thesaurus changes (GeoNode#14098) [Fixes GeoNode#14109] Fixes Dataset creation from JSON Schema fails for LineString (GeoNode#14110) Renamed docs folder [Fixes GeoNode#14035] Implementation of a common ResourceManager base class for all resource types (GeoNode#14053) moving the example in the end of this section adding docs for the social account group sync [Fixes GeoNode#14042] deprecate overwrite_existing_layers in favor of action… (GeoNode#14043) [Fixes GeoNode#13936] Support for XLSX File Uploads in GeoNode (GeoNode#13937) ...
Updates GeoNode's i18n caching logic so that changes to the
labels-i18nThesaurus reliably invalidate previously cached localized label data (and related i18n-derived caches) instead of continuing to serve stale values.Changes Made
datechanges, the entire in-memorylang_cacheis cleared (all languages) rather than only invalidating the current(lang, data_key)lookup, ensuring no stale data is served for any language.lang_cachemutations (set(),clear(),force_check()) are now guarded with_lock, making cache invalidation atomic across concurrent readers and writers. The DB query inset()is kept outside the lock to avoid holding it during I/O.test_stale_cache_invalidated_on_thesaurus_updateingeonode/metadata/tests/test_i18n.pyto reproduce the stale-cache scenario — it warms up the cache for multiple languages (enandit), bumps the Thesaurusdate, and asserts that all language caches are rebuilt with fresh values.