feat(hunspell): Add reload_cached_resources in TokenFilterFactory to support dictionary hot-reload - #21559
Conversation
PR Reviewer Guide 🔍(Review updated until commit 7e3bf82)Here are some key observations to aid the review process:
|
PR Code Suggestions ✨Latest suggestions up to 7e3bf82 Explore these optional code suggestions:
Previous suggestionsSuggestions up to commit c08d099
Suggestions up to commit e9bd98c
Suggestions up to commit c6d6c62
Suggestions up to commit 353a7a0
Suggestions up to commit 1ca69e4
|
There was a problem hiding this comment.
Pull request overview
Adds an opt-in Hunspell dictionary cache invalidation path so that updated dictionary files on disk can be picked up during search analyzer reloads without restarting nodes.
Changes:
- Add
reloadSearchAnalyzers(registry, boolean invalidateCache)to optionally invalidate Hunspell caches before rebuilding reloadable analyzers. - Add
HunspellService.invalidateDictionary(cacheKey)andHunspellTokenFilterFactory.invalidateCache()to support targeted eviction (traditional locale andref_pathkeys). - Add tests covering cache eviction and
updateable/AnalysisModebehavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| server/src/main/java/org/opensearch/index/mapper/MapperService.java | Adds an overload to optionally invalidate Hunspell caches before reloading search analyzers. |
| server/src/main/java/org/opensearch/index/analysis/HunspellTokenFilterFactory.java | Adds updateable→AnalysisMode.SEARCH_TIME support and exposes a cache invalidation helper. |
| server/src/main/java/org/opensearch/indices/analysis/HunspellService.java | Adds dictionary cache eviction by cache key. |
| server/src/test/java/org/opensearch/indices/analyze/HunspellServiceTests.java | Adds unit tests for service-level cache invalidation behavior. |
| server/src/test/java/org/opensearch/index/analysis/HunspellTokenFilterFactoryTests.java | Adds tests for updateable mode and invalidation behavior (including a simulated invalidation walk). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
The RaceCondition indicated by the comment above it theoretically possible but not a real concern in practice, because:
So the window doesn't exist in practice. The dictionary is only re-fetched from cache during factory construction (inside reload()), which happens immediately after invalidation within the same synchronized |
|
❌ Gradle check result for 4003f88: null Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
4003f88 to
d901c4f
Compare
d901c4f to
dc14993
Compare
dc14993 to
353e1d2
Compare
Signed-off-by: shayush622 <ayush5267@gmail.com>
e9bd98c to
c08d099
Compare
|
Persistent review updated to latest commit c08d099 |
|
Persistent review updated to latest commit 7e3bf82 |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❌ Gradle check result for 7e3bf82: FAILURE Please examine the workflow log, locate, and copy-paste the failure(s) below, then iterate to green. Is the failure a flaky test unrelated to your change? |
|
❕ Gradle check result for 7e3bf82: UNSTABLE Please review all flaky tests that succeeded after retry and create an issue if one does not already exist to track the flaky failure. |
…ad (opensearch-project#21559) Signed-off-by: shayush622 <ayush5267@gmail.com> Co-authored-by: shwetathareja <shwetathareja@live.com> Signed-off-by: Khishorekumar BS <bkhishor@amazon.com>
Description
Adds cache reload support to enable hot-reload of hunspell dictionaries via the existing _refresh_search_analyzers API without requiring a node restart.
Problem: When hunspell dictionary files are updated on disk, calling _refresh_search_analyzers rebuilds the analyzer factories but reuses the cached Dictionary object from HunspellService's node-level cache. The
only way to pick up new dictionary content was to restart the node.
Solution: Add a boolean reloadCachedResources parameter to MapperService.reloadSearchAnalyzers(). When true, the method walks each ReloadableCustomAnalyzer's token filters and calls reloadCachedResources() — a
new default method on TokenFilterFactory. HunspellTokenFilterFactory overrides it to atomically reload its dictionary from disk into the cache (no eviction window). The rebuilt factory then picks up the fresh
dictionary.
Changes:
reload walk.
Related
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here
(https://github.com/opensearch-project/OpenSearch/blob/main/CONTRIBUTING.md#developer-certificate-of-origin).