-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[Fixes #14097] Label thesaurus is not reloaded on thesaurus changes #14098
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fe1845b
a2745f9
d6add25
d87d0cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -115,7 +115,8 @@ def get_entry(self, lang, data_key): | |
| .first() | ||
| ) | ||
| 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 | ||
|
Comment on lines
117
to
120
|
||
| if not cached_entry: | ||
| logger.info(f"Cache for {lang}:{data_key} needs to be created") | ||
|
|
@@ -126,31 +127,35 @@ def get_entry(self, lang, data_key): | |
|
|
||
| def set(self, lang: str, data_key: str, data, request_date: str): | ||
| # TODO: check if lang is allowed | ||
| cached_entry: I18nCacheEntry = self.lang_cache.setdefault(lang, I18nCacheEntry()) | ||
|
|
||
| # Perform DB query outside the lock to avoid holding it during I/O | ||
| latest_date = ( | ||
| Thesaurus.objects.filter(identifier=I18N_THESAURUS_IDENTIFIER).values_list("date", flat=True).first() | ||
| ) | ||
|
|
||
| if request_date == latest_date: | ||
| # no changes after processing, set the info right away | ||
| logger.debug(f"Caching lang:{lang} key:{data_key} date:{request_date}") | ||
| cached_entry.date = latest_date | ||
| cached_entry.caches[data_key] = data | ||
| return True | ||
| else: | ||
| logger.warning( | ||
| f"Cache will not be updated for lang:{lang} key:{data_key} reqdate:{request_date} latest:{latest_date}" | ||
| ) | ||
| return False | ||
| with self._lock: | ||
| cached_entry: I18nCacheEntry = self.lang_cache.setdefault(lang, I18nCacheEntry()) | ||
|
|
||
| if request_date == latest_date: | ||
| # no changes after processing, set the info right away | ||
| logger.debug(f"Caching lang:{lang} key:{data_key} date:{request_date}") | ||
| cached_entry.date = latest_date | ||
| cached_entry.caches[data_key] = data | ||
| return True | ||
| else: | ||
| logger.warning( | ||
| f"Cache will not be updated for lang:{lang} key:{data_key} reqdate:{request_date} latest:{latest_date}" | ||
| ) | ||
| return False | ||
|
|
||
| def clear(self): | ||
| logger.info("Clearing i18n cache") | ||
| self.lang_cache.clear() | ||
| with self._lock: | ||
| self.lang_cache.clear() | ||
|
|
||
| def force_check(self): | ||
| """For testing: forces a check against the DB on the next get_entry call.""" | ||
| self._last_check = 0 | ||
| with self._lock: | ||
| self._last_check = 0 | ||
|
|
||
|
|
||
| class LabelResolver: | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
get_entry()now clearsself.lang_cacheunder_lock, butset()andclear()mutateself.lang_cachewithout acquiring the same lock. This creates a real race where one thread can be insetdefault()/write while another thread clears the dict, leading to lost updates and inconsistent cache state. Consider guarding alllang_cachemutations (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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot apply changes based on this feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied in commit a2745f9. All
lang_cachemutations (set(),clear(),force_check()) are now guarded with_lock. The DB query inset()is intentionally kept outside the lock to avoid holding it during I/O, with only the actual cache mutations inside the lock context.