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

Aias00 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 12502edda3 fix(register): key URI retry fallbacks by namespace (#7639)
12502edda3 is described below

commit 12502edda310cd889df931285d0b74422033e4eb
Author: Sean-Walker0 <[email protected]>
AuthorDate: Mon Oct 19 09:39:07 2026 +0800

    fix(register): key URI retry fallbacks by namespace (#7639)
    
    The fallback retry map keyed pending URI registrations by selector
    name and RPC plugin name only, although FallbackHolder carries the
    namespace. A successful registration of the same selector name in
    another namespace removed the first namespace's pending retry, and a
    failed one replaced its identity, so cross-namespace registrations
    silently dropped or corrupted each other's retry state.
    
    Include the namespace in the key used consistently by enqueue,
    removal and recovery. Regression test registers the same selector
    name in two namespaces and asserts the failing namespace's pending
    retry survives the other namespace's success (red on the previous
    code, which removed it).
    
    Fixes #7636
    
    Co-authored-by: Sean-Walker0 
<[email protected]>
---
 .../FallbackShenyuClientRegisterService.java       |  6 +--
 .../FallbackShenyuClientRegisterServiceTest.java   | 56 ++++++++++++++++++++++
 2 files changed, 59 insertions(+), 3 deletions(-)

diff --git 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterService.java
 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterService.java
index 1e5046f6ce..462bea6710 100644
--- 
a/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterService.java
+++ 
b/shenyu-admin/src/main/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterService.java
@@ -60,7 +60,7 @@ public abstract class FallbackShenyuClientRegisterService 
implements ShenyuClien
     @Override
     public String registerURI(final String selectorName, final 
List<URIRegisterDTO> uriList, final String namespaceId) {
         String result;
-        String key = key(selectorName);
+        String key = key(selectorName, namespaceId);
         try {
             this.removeFallBack(key);
             result = this.doRegisterURI(selectorName, uriList, namespaceId);
@@ -103,8 +103,8 @@ public abstract class FallbackShenyuClientRegisterService 
implements ShenyuClien
         }
     }
 
-    private String key(final String selectorName) {
-        return String.join(":", selectorName, 
PluginNameAdapter.rpcTypeAdapter(rpcType()));
+    private String key(final String selectorName, final String namespaceId) {
+        return String.join(":", selectorName, 
PluginNameAdapter.rpcTypeAdapter(rpcType()), namespaceId);
     }
 
     /**
diff --git 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterServiceTest.java
 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterServiceTest.java
index 7ee4ac7e9a..4412bca9f5 100644
--- 
a/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterServiceTest.java
+++ 
b/shenyu-admin/src/test/java/org/apache/shenyu/admin/service/register/FallbackShenyuClientRegisterServiceTest.java
@@ -23,13 +23,16 @@ import 
org.apache.shenyu.register.common.dto.ApiDocRegisterDTO;
 import org.apache.shenyu.register.common.dto.MetaDataRegisterDTO;
 import org.apache.shenyu.register.common.dto.URIRegisterDTO;
 import org.junit.jupiter.api.Test;
+import org.springframework.test.util.ReflectionTestUtils;
 
 import java.util.ArrayList;
+import java.util.Map;
 import java.util.Collections;
 import java.util.List;
 
 import static 
org.apache.shenyu.common.constant.Constants.SYS_DEFAULT_NAMESPACE_ID;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 
 /**
@@ -47,6 +50,23 @@ class FallbackShenyuClientRegisterServiceTest {
         assertEquals(StringUtils.EMPTY, 
mockFallbackShenyuClientRegisterServiceException.registerURI("Selector_Name", 
new ArrayList<>(), SYS_DEFAULT_NAMESPACE_ID));
     }
 
+
+    @Test
+    public void fallbackRetryIsNamespaced() throws Exception {
+        final NamespacedFailService service = new NamespacedFailService();
+        // namespace A fails and queues a pending retry
+        service.registerURI("orders", new ArrayList<>(), "ns-a");
+        // namespace B registers the same selector name successfully
+        service.registerURI("orders", new ArrayList<>(), "ns-b");
+
+        @SuppressWarnings("unchecked")
+        final Map<String, Object> falls = (Map<String, Object>) 
ReflectionTestUtils.getField(service, "fallsRegisters");
+        assertTrue(falls.keySet().stream().anyMatch(key -> 
key.endsWith(":ns-a")),
+                "namespace A's pending retry must survive namespace B's 
registration of the same selector name");
+        assertTrue(falls.keySet().stream().noneMatch(key -> 
key.endsWith(":ns-b")),
+                "namespace B's successful registration must not leave a 
pending retry");
+    }
+
     @Test
     public void testHeartbeat() {
 
@@ -85,6 +105,42 @@ class FallbackShenyuClientRegisterServiceTest {
         mockService.checkNamespacePluginRel("namespace", "plugin");
     }
 
+
+    static class NamespacedFailService extends 
FallbackShenyuClientRegisterService {
+
+        @Override
+        String doRegisterURI(final String selectorName, final 
List<URIRegisterDTO> uriList, final String namespaceId) {
+            if ("ns-a".equals(namespaceId)) {
+                throw new RuntimeException("namespace A registration backend 
down");
+            }
+            return "ok";
+        }
+
+        @Override
+        String doHeartbeat(final String selectorName, final 
List<URIRegisterDTO> uriList, final String namespaceId) {
+            return "ok";
+        }
+
+        @Override
+        public String rpcType() {
+            return "grpc";
+        }
+
+        @Override
+        public String register(final MetaDataRegisterDTO metaDataRegisterDTO) {
+            return null;
+        }
+
+        @Override
+        public String registerApiDoc(final ApiDocRegisterDTO 
apiDocRegisterDTO) {
+            return null;
+        }
+
+        @Override
+        public void checkNamespacePluginRel(final String namespaceId, final 
String pluginName) {
+        }
+    }
+
     static class MockFallbackShenyuClientRegisterService extends 
FallbackShenyuClientRegisterService {
 
         @Override

Reply via email to