Aias00 opened a new issue, #6857: URL: https://github.com/apache/shenyu/issues/6857
## Description `findUpstreamListBySelectorId` returns `task.getHealthyUpstream().get(selectorId)` — a direct reference to the live `ArrayList` stored in `UpstreamCheckTask.healthyUpstream` (a `ConcurrentMap` of plain `ArrayList` values). The health-check thread modifies this same list under `synchronized(lock)`: `putToMap` calls `list.add(upstream)` and `removeFromMap` calls `list.remove(upstream)`. However, the readers (`DividePlugin:94`, `WebSocketPlugin:92`, `ApacheDubboGrayLoadBalance:57`, `DefaultRetryStrategy:109`) iterate and index the returned list on request threads WITHOUT acquiring `lock`. `ArrayList` is not thread-safe: a concurrent `add` (which may trigger `Arrays.copyOf` resize) or `remove` (which shifts elements via `System.arraycopy`) while a reader calls `size()` then `get(i)` can produce `IndexOutOfBoundsException`, null reads, or stale/inconsistent list state. ## Location - `shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java:128` - `shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCheckTask.java:289-292,305-308,355` - `shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-divide/src/main/java/org/apache/shenyu/plugin/divide/DividePlugin.java:94` ## Impact Occasional `IndexOutOfBoundsException` or NPE in the load balancer during a health-check cycle, causing intermittent 500 errors for proxied requests. Also possible: load balancer sees a partially-updated list (missing or phantom upstreams), routing to a stale or non-existent endpoint. ## Suggested fix Either (a) return a snapshot copy from `findUpstreamListBySelectorId` (`new ArrayList<>(list)` under `synchronized(lock)`), or (b) change the `healthyUpstream` values to `CopyOnWriteArrayList` so readers get a consistent snapshot. Option (b) is lower overhead for the read-heavy path. ## Related existing None — distinct from #6570 (BaseDataCache.removeSelectData/removeRuleData mutate live list in place) which covers `shenyu-common`'s selector/rule cache, and distinct from N35 (admin-side `UpstreamCheckService.fetchUpstreamData` LinkedList in `shenyu-admin`). This covers the gateway-side `UpstreamCacheManager`/`UpstreamCheckTask` in `shenyu-loadbalancer`. -- 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]
