[ISSUE #9308]For the orchestration of configuration filters, there are the following areas that can be optimized #9309 - #15034
Conversation
# Conflicts: # client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManager.java # client/src/test/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManagerTest.java
|
Thanks for your this PR. 🙏 感谢您提交的PR。 🙏 |
|
|
||
| IConfigContext configContext = configRequest.getConfigContext(); | ||
There was a problem hiding this comment.
Please don't change the indent
|
@CLFutureX So sorry, nacos currently is doing spotless auto reformat code works so that your pr is conflict with this work. Please solve conflict and use |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
|
@CLFutureX Sorry, there is one file is in conflicts. Please help to resolve it. |
|
This PR has conflicts with the git fetch origin
git checkout RapperCL_fix_9308_new
git rebase origin/develop
# resolve conflicts, then:
git push --force-with-leaseThis is a one-time reminder. Feel free to @mention me for a re-review after conflicts are resolved. Automated notification by github-manager-bot |
nacos-community
left a comment
There was a problem hiding this comment.
This PR refactors the client config filter chain so doFilter() no longer allocates a new VirtualFilterChain per invocation, using a prebuilt immutable linked chain instead. The direction is good and execution order is preserved, but the shared filterChain field lacks a visibility guarantee for reader threads — please address the critical finding below.
Findings
- [Critical] client/src/main/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainManager.java:41 —
filterChainshould bevolatileto prevent stale/null reads from unsynchronizeddoFilter(). - [Warning] ConfigFilterChainManager.java:55 —
buildConfigFilterChain()should beprivate, not public. - [Info] ConfigFilterChainManager.java:49 — redundant final
buildConfigFilterChain()call in the constructor. - [Info] ConfigFilterChainManager.java:92 — chain rebuilt on every
addFilter(), making bulk init O(n²). - [Info] client/src/test/java/com/alibaba/nacos/client/config/filter/impl/ConfigFilterChainTest.java:30 — no coverage for the new structure or concurrency.
Suggestions
private volatile IConfigFilterChain filterChain;(or hold the chain in afinalholder published safely) is the minimal fix.- Consider rebuilding the chain only once after the initial ServiceLoader batch, and making
buildConfigFilterChain()private.
Automated review by github-manager-bot
| private final Properties initProperty; | ||
|
|
||
|
|
||
| private IConfigFilterChain filterChain; |
There was a problem hiding this comment.
filterChain is a non-volatile field written in the constructor / synchronized addFilter() and read from unsynchronized doFilter(). Client config filters run on listener/worker threads, so readers may observe a stale or null chain. Change to private volatile IConfigFilterChain filterChain; to ensure safe publication on every rebuild.
| /** | ||
| * Build ConfigFilterChain. | ||
| */ | ||
| public void buildConfigFilterChain() { |
There was a problem hiding this comment.
buildConfigFilterChain() is declared public but is only an internal implementation detail used by this class. Reduce API surface by making it private to avoid exposing new public methods in the client module.
| for (IConfigFilter configFilter : configFilters) { | ||
| addFilter(configFilter); | ||
| } | ||
| buildConfigFilterChain(); |
There was a problem hiding this comment.
The constructor already triggers buildConfigFilterChain() inside each addFilter() call, so this final call is redundant. Consider building the chain only once after all initial filters are added.
| this.filters.add(i, filter); | ||
| } | ||
| buildConfigFilterChain(); | ||
| return this; |
There was a problem hiding this comment.
addFilter() rebuilds the entire chain from scratch on every insertion, making bulk initialization (e.g., ServiceLoader in the constructor) O(n²). For typical filter counts this is fine, but consider whether the chain should be rebuilt only once after batch additions.
| @@ -28,6 +28,7 @@ void testConfigFilterChain() { | |||
| ConfigFilterChainManager configFilterChainManager = new ConfigFilterChainManager(null); | |||
| configFilterChainManager.addFilter(new DemoFilter1()); | |||
| configFilterChainManager.addFilter(new DemoFilter2()); | |||
There was a problem hiding this comment.
The test change is only a blank line. Existing coverage preserves ordering with two filters, but does not exercise the new linked-node structure or guard against the visibility issue. Consider adding a multi-thread doFilter test or a test that verifies the chain is not recreated per invocation.
This PR replaces the previous one. See below for detailed changes. old pr