fix: make upstream lists thread-safe (#6857) - #7062
juicewcode wants to merge 8 commits into
Conversation
Use CopyOnWriteArrayList for healthy and unhealthy upstream collections so request threads can safely iterate while health-check threads update them. Add a regression test covering snapshot iteration and visibility of subsequent upstream updates.
There was a problem hiding this comment.
🟡 Changes recommended
One or more issues must be addressed before approval.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
This PR improves concurrent access to gateway upstream lists during health checks.
Changes:
- Uses
CopyOnWriteArrayListfor upstream map values. - Adds iterator snapshot and update visibility regression coverage.
File summaries
| File | Description |
|---|---|
| shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManagerTest.java | Updated as part of this pull request. |
| shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCheckTask.java | Updated as part of this pull request. |
Review details
Suppressed comments (1)
shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManagerTest.java:89
- This fixture leaves health checking enabled (the
Upstreambuilder defaults it totrue) while the singleton manager starts a scheduled health-check thread. The syntheticcopy-on-write-url:8080is not a reachable endpoint, so that thread can mark it unhealthy and remove it betweensubmitand the size assertion, making this regression test flaky. Disable health checking for this fixture so only the explicittriggerAddOnechanges the list.
final Upstream upstream = Upstream.builder().url("copy-on-write-url:8080").status(true).build();
- Files reviewed: 2/2 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| List<Upstream> list = MapUtils.computeIfAbsent(map, selectorId, k -> new CopyOnWriteArrayList<>()); | ||
| if (!list.contains(upstream)) { | ||
| list.add(upstream); |
…ist-thread-safety
Return a per-request snapshot from findUpstreamListBySelectorId so index-based load balancers observe a stable list while health-check updates are in progress. Update the regression test to verify that existing snapshots remain unchanged and subsequent requests observe newly added upstreams.
There was a problem hiding this comment.
🟡 Changes recommended
The regression test does not verify the internal copy-on-write collection or iterator guarantee described by the PR.
Get a fresh assessment by requesting another Copilot review.
Review details
- Files reviewed: 3/3 changed files
- Comments generated: 1
- Review effort level: Balanced
| List<Upstream> snapshot = upstreamCacheManager.findUpstreamListBySelectorId(selectorId); | ||
| Upstream added = Upstream.builder().url("added-url:8080").status(true).build(); | ||
| getUpstreamCheckTask(upstreamCacheManager).triggerAddOne(selectorId, added); | ||
|
|
||
| Assertions.assertEquals(1, snapshot.size()); | ||
| Assertions.assertSame(upstream, snapshot.get(0)); | ||
| Assertions.assertEquals(2, upstreamCacheManager.findUpstreamListBySelectorId(selectorId).size()); |
Aias00
left a comment
There was a problem hiding this comment.
Approved as PMC (Aias00). Small, well-scoped fix with regression tests; green CI, mergeable. Reviewed the diff.
Fixes #6857
Summary
ArrayListinstances withCopyOnWriteArrayList.Test
CopyOnWriteArrayList.Make sure that:
./mvnw clean install -Dmaven.javadoc.skip=true.