TheoLi0905 opened a new issue, #7018:
URL: https://github.com/apache/shenyu/issues/7018
### Is there an existing issue for this?
- [x] I have searched the existing issues
### Current Behavior
`BaseDataCache` stores selector and rule data in:
- `ConcurrentMap<String, List<SelectorData>>`
- `ConcurrentMap<String, List<RuleData>>`
The map is concurrent, but its values are mutable `ArrayList` instances.
`removeSelectData` and `removeRuleData` modify the published list in place by
calling `removeIf` inside `synchronized (SELECTOR_MAP/RULE_MAP)`.
However, request threads obtain the same list instance through
`obtainSelectorData` and `obtainRuleData`, and iterate it without acquiring
the
same lock in `AbstractShenyuPlugin#matchSelector` and `#matchRule`.
Therefore, when Admin synchronizes a selector/rule DELETE event while
Bootstrap
is processing requests, the request thread may still throw
`ConcurrentModificationException`.
### Related issue
This is related to #4071 and PR #4155.
PR #4155 serialized cache writers, but readers do not acquire the same lock,
so
it does not completely prevent concurrent modification of the shared list.
### Proposed Solution
Use an immutable-snapshot/copy-on-write approach in `BaseDataCache`:
1. Read the current list inside the existing synchronized block.
2. Create a new list excluding the deleted item.
3. Replace the map value with the new list.
4. Never modify a list after it has been published to request threads.
Add regression tests verifying that a previously obtained list remains
unchanged after selector/rule deletion.
### Expected Behavior
Selector and rule cache reads should use stable snapshots. Deleting cache
data
should create a new list and atomically replace the map value instead of
modifying a list already exposed to request threads.
### Steps To Reproduce
_No response_
### Environment
```markdown
ShenYu version(s): current master
```
### Debug logs
_No response_
### Anything else?
### Proposed solution
Use a stable-snapshot/copy-on-write approach in `BaseDataCache`:
1. Obtain the current list inside the existing synchronized block.
2. Create a new list excluding the deleted selector or rule.
3. Atomically replace the map value with the new list.
4. Never structurally modify a list after it has been published to request
threads.
5. Add regression tests verifying that a previously obtained selector/rule
list
remains unchanged after deletion.
This proposal does not require request threads to acquire a global lock and
is
consistent with the existing update path, which already creates and replaces
lists.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]