Refactor Selector - #6336
Refactor Selector#6336chaooil wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
This PR refactors selector/rule matching in AbstractShenyuPlugin to properly leverage the existing two-level match cache (L1 WindowTinyLFU + L2 matching strategy), and adds targeted tests to cover L1 cache-hit behavior.
Changes:
- Fix selector/rule execution flow to return immediately on L1 cache hits (including cached negative-match sentinels).
- Refactor match-caching logic via a shared
cacheMatchData(...)helper and minor hot-path optimizations in matching. - Add unit tests validating L1 cache-hit and negative-sentinel short-circuit behavior for both selector and rule matching.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/AbstractShenyuPlugin.java | Refactors selector/rule lookup to correctly use L1 cache hits and consolidates match-caching logic. |
| shenyu-plugin/shenyu-plugin-base/src/test/java/org/apache/shenyu/plugin/base/AbstractShenyuPluginTest.java | Adds tests covering selector/rule L1 cache hits and negative-sentinel short-circuit cases. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Aias00
left a comment
There was a problem hiding this comment.
Thanks @2823602869!
This refactor makes the L1 match cache actually work as designed. In the current code, even after an L1 hit, execute() unconditionally overwrites the result with defaultMatchSelector/defaultMatchRule, so positive L1 entries were dead weight and every request paid for full L2 matching. The new twoLevelCacheLookupSelector/twoLevelCacheLookupRule short-circuit on an L1 hit and only fall to L2 on a miss, which finally matches the documented intent of the cache (and the negative-cache/sentinel behavior is preserved via the isBlank(id) → null-handle check).
I verified the safety of the positive-hit short-circuit: CommonPluginDataSubscriber invalidates MatchDataCache on selector/rule update, delete, and refresh events (including the empty sentinels via removeEmptySelectorData/removeEmptyRuleData), so data changes still propagate to the L1 layer before a stale entry could be served.
The other parts are clean as well:
- The generic
cacheMatchData+CacheWriterdedupes two near-identical blocks without behavior change. - The loop-based
matchSelector/matchRulewithLinkedHashSetpreserves the olddistinct()+ ordering semantics while cutting stream allocations on the hot path;manyMatchSelector/manyMatchRuleproduce the same grouping/max-key/min-sort result as before. - The four new tests pin the L1-hit and sentinel short-circuit behavior for both selector and rule paths, and the full CI matrix is green.
Two minor notes (non-blocking):
cacheMatchDatatreats onlyObjects.isNull(id)as the sentinel case, whereas the old code usedStringUtils.isBlank(id)— equivalent for the built-in sentinels (null id), but if a selector ever carried an empty-string id it would no longer be negatively cached; it would just re-match, so worst case is a performance edge, not correctness.- The file is missing a trailing newline now — checkstyle evidently tolerates it (CI is green), but worth fixing in a squash.
LGTM, approving.
Aias00
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES (PMC Aias00): this PR has merge conflicts (CONFLICTING) and cannot be merged. Please rebase onto the latest master and resolve the conflicts, then request a re-review.
|
pls fix conflicts |
- add twoLevelCacheLookupSelector/twoLevelCacheLookupRule so an L1 hit short-circuits the L2 matching - extract a shared cacheMatchData helper for positive and negative caching - use StringUtils.isBlank as the null-id sentinel check
a6a6d24 to
98dbcc7
Compare
Refactor Selector #6290
Make sure that:
./mvnw clean install -Dmaven.javadoc.skip=true.