This is an automated email from the ASF dual-hosted git repository.

liuhongyu pushed a commit to branch fix/fix_upstream_check
in repository https://gitbox.apache.org/repos/asf/shenyu.git

commit 099c0cbbd5024711ce532a2198ff264732c87d10
Author: liuhy <[email protected]>
AuthorDate: Tue Feb 10 08:52:29 2026 +0800

    fix: improve upstream cache management and add recovery test for empty 
events
---
 .../loadbalancer/cache/UpstreamCacheManager.java   |  7 ++--
 .../shenyu/loadbalancer/entity/Upstream.java       |  2 +-
 .../cache/UpstreamCacheManagerTest.java            | 38 ++++++++++++++++++++++
 .../shenyu/loadbalancer/entity/UpstreamTest.java   |  8 +++++
 4 files changed, 52 insertions(+), 3 deletions(-)

diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
index 2c13303970..246eace594 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManager.java
@@ -150,8 +150,11 @@ public final class UpstreamCacheManager {
 
         // Check if the list is empty first to avoid unnecessary processing
         if (actualUpstreamList.isEmpty()) {
-            List<Upstream> existUpstreamList = 
MapUtils.computeIfAbsent(UPSTREAM_MAP, selectorId, k -> Lists.newArrayList());
-            removeAllUpstreams(selectorId, existUpstreamList);
+            List<Upstream> existUpstreamList = UPSTREAM_MAP.get(selectorId);
+            if (Objects.nonNull(existUpstreamList)) {
+                removeAllUpstreams(selectorId, existUpstreamList);
+            }
+            UPSTREAM_MAP.remove(selectorId);
             return;
         }
 
diff --git 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
index 36656e3493..d832dc28ff 100644
--- 
a/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
+++ 
b/shenyu-loadbalancer/src/main/java/org/apache/shenyu/loadbalancer/entity/Upstream.java
@@ -509,7 +509,7 @@ public final class Upstream {
 
     @Override
     public int hashCode() {
-        return Objects.hash(protocol, url, weight);
+        return Objects.hash(protocol, url);
     }
 
     @Override
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManagerTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManagerTest.java
index 17b449df3c..53290d867b 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManagerTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/cache/UpstreamCacheManagerTest.java
@@ -278,6 +278,44 @@ public class UpstreamCacheManagerTest {
         upstreamCacheManager.removeByKey(testSelectorId);
     }
 
+    @Test
+    @Order(10)
+    public void testSubmitCanRecoverAfterEmptyUpstreamEvent() {
+        final UpstreamCacheManager upstreamCacheManager = 
UpstreamCacheManager.getInstance();
+        final String testSelectorId = "RECOVER_AFTER_EMPTY_EVENT_TEST";
+
+        List<Upstream> initialList = new ArrayList<>(1);
+        initialList.add(Upstream.builder()
+                .protocol("http://";)
+                .url("recover-upstream:8080")
+                .status(true)
+                .healthCheckEnabled(false)
+                .build());
+        upstreamCacheManager.submit(testSelectorId, initialList);
+        List<Upstream> firstSubmitResult = 
upstreamCacheManager.findUpstreamListBySelectorId(testSelectorId);
+        Assertions.assertNotNull(firstSubmitResult);
+        Assertions.assertFalse(firstSubmitResult.isEmpty());
+
+        upstreamCacheManager.submit(testSelectorId, new ArrayList<>());
+        List<Upstream> afterEmptySubmitResult = 
upstreamCacheManager.findUpstreamListBySelectorId(testSelectorId);
+        Assertions.assertTrue(Objects.isNull(afterEmptySubmitResult) || 
afterEmptySubmitResult.isEmpty());
+
+        List<Upstream> recoveredList = new ArrayList<>(1);
+        recoveredList.add(Upstream.builder()
+                .protocol("http://";)
+                .url("recover-upstream:8080")
+                .status(true)
+                .healthCheckEnabled(false)
+                .build());
+        upstreamCacheManager.submit(testSelectorId, recoveredList);
+        List<Upstream> secondSubmitResult = 
upstreamCacheManager.findUpstreamListBySelectorId(testSelectorId);
+        Assertions.assertNotNull(secondSubmitResult);
+        Assertions.assertFalse(secondSubmitResult.isEmpty());
+        Assertions.assertTrue(secondSubmitResult.stream().anyMatch(upstream -> 
"recover-upstream:8080".equals(upstream.getUrl())));
+
+        upstreamCacheManager.removeByKey(testSelectorId);
+    }
+
     /**
      * Helper method to get the UpstreamCheckTask using reflection.
      */
diff --git 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
index 9a9146f6b0..ab7d009707 100644
--- 
a/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
+++ 
b/shenyu-loadbalancer/src/test/java/org/apache/shenyu/loadbalancer/entity/UpstreamTest.java
@@ -73,7 +73,15 @@ public class UpstreamTest {
                 .weight(1)
                 .status(true)
                 .build();
+        Upstream upstream4 = Upstream.builder()
+                .protocol("https://";)
+                .url("url")
+                .weight(2)
+                .status(true)
+                .build();
         Assertions.assertEquals(upstream2, upstream3);
+        Assertions.assertEquals(upstream2, upstream4);
+        Assertions.assertEquals(upstream2.hashCode(), upstream4.hashCode());
         Assertions.assertNotNull(upstream2.toString());
         Assertions.assertTrue(upstream2.hashCode() >= 0);
     }

Reply via email to