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]

Reply via email to