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 23ed3815d8 fix(plugin): bound metadata path cache (#7158)
23ed3815d8 is described below

commit 23ed3815d8819101b1f63225d76e1c88e63d2b5a
Author: Liming Deng <[email protected]>
AuthorDate: Thu Oct 1 06:28:55 2026 +0800

    fix(plugin): bound metadata path cache (#7158)
---
 .../shenyu/common/cache/WindowTinyLFUMap.java      |  1 +
 .../shenyu/plugin/base/cache/MetaDataCache.java    | 28 ++++-----------------
 .../plugin/global/cache/MetaDataCacheTest.java     | 29 ++++++++++++++++++++++
 3 files changed, 35 insertions(+), 23 deletions(-)

diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/cache/WindowTinyLFUMap.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/cache/WindowTinyLFUMap.java
index 826b645e4e..80edc07574 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/cache/WindowTinyLFUMap.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/cache/WindowTinyLFUMap.java
@@ -135,6 +135,7 @@ public class WindowTinyLFUMap<K, V> extends AbstractMap<K, 
V> implements Seriali
     
     @Override
     public int size() {
+        this.cache.cleanUp();
         return this.cache.asMap().entrySet().size();
     }
     
diff --git 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
index 344fa049ca..0ef7a49f9c 100644
--- 
a/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
+++ 
b/shenyu-plugin/shenyu-plugin-base/src/main/java/org/apache/shenyu/plugin/base/cache/MetaDataCache.java
@@ -18,6 +18,7 @@
 package org.apache.shenyu.plugin.base.cache;
 
 import com.google.common.collect.Maps;
+import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.cache.WindowTinyLFUMap;
 import org.apache.shenyu.common.dto.MetaData;
 import org.apache.shenyu.plugin.base.utils.PathMatchUtils;
@@ -25,9 +26,7 @@ import org.apache.shenyu.plugin.base.utils.PathMatchUtils;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.Set;
 import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.ConcurrentSkipListSet;
 
 /**
  * The type Meta data cache.
@@ -45,12 +44,8 @@ public final class MetaDataCache {
      */
     private static final ConcurrentMap<String, MetaData> META_DATA_MAP = 
Maps.newConcurrentMap();
 
-    private static final WindowTinyLFUMap<String, MetaData> CACHE = new 
WindowTinyLFUMap<>(1 << 16, Integer.MAX_VALUE, Boolean.FALSE);
-
-    /**
-     * pathPattern -> path.
-     */
-    private static final ConcurrentMap<String, Set<String>> MAPPING = 
Maps.newConcurrentMap();
+    private static final WindowTinyLFUMap<String, MetaData> CACHE =
+            new WindowTinyLFUMap<>(Constants.CACHE_MAX_COUNT, 
Constants.CACHE_MAX_COUNT, Boolean.FALSE);
 
     private MetaDataCache() {
     }
@@ -99,16 +94,10 @@ public final class MetaDataCache {
     private void clean(final String key) {
         if (key.contains("*")) {
             CACHE.clear();
-            MAPPING.clear();
             return;
         }
-        // springCloud and divide are needs to be cleaned
-        Optional.ofNullable(MAPPING.get(key))
-                .ifPresent(paths -> {
-                    for (String path : paths) {
-                        CACHE.remove(path);
-                    }
-                });
+        CACHE.entrySet().removeIf(entry -> Objects.equals(key, 
NULL.equals(entry.getValue())
+                ? DIVIDE_CACHE_KEY : entry.getValue().getPath()));
     }
 
     /**
@@ -152,13 +141,6 @@ public final class MetaDataCache {
     public void initCache(final String path, final MetaData value, final 
String metaPath) {
         // The extreme case will lead to OOM, that's why use LRU
         CACHE.put(path, Optional.ofNullable(value).orElse(NULL));
-        // spring/** -> Collections 'spring/A', 'spring/B'
-        Set<String> paths = MAPPING.get(metaPath);
-        if (Objects.isNull(paths)) {
-            MAPPING.putIfAbsent(metaPath, new ConcurrentSkipListSet<>());
-            paths = MAPPING.get(metaPath);
-        }
-        paths.add(path);
     }
     
     /**
diff --git 
a/shenyu-plugin/shenyu-plugin-global/src/test/java/org/apache/shenyu/plugin/global/cache/MetaDataCacheTest.java
 
b/shenyu-plugin/shenyu-plugin-global/src/test/java/org/apache/shenyu/plugin/global/cache/MetaDataCacheTest.java
index f922e21eec..e00b96ff7f 100644
--- 
a/shenyu-plugin/shenyu-plugin-global/src/test/java/org/apache/shenyu/plugin/global/cache/MetaDataCacheTest.java
+++ 
b/shenyu-plugin/shenyu-plugin-global/src/test/java/org/apache/shenyu/plugin/global/cache/MetaDataCacheTest.java
@@ -17,14 +17,17 @@
 
 package org.apache.shenyu.plugin.global.cache;
 
+import org.apache.shenyu.common.constant.Constants;
 import org.apache.shenyu.common.dto.MetaData;
 import org.apache.shenyu.plugin.base.cache.MetaDataCache;
+import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
  * The Test Case For MetaDataCache.
@@ -44,6 +47,12 @@ public final class MetaDataCacheTest {
         metaDataCache = MetaDataCache.getInstance();
     }
 
+    @AfterEach
+    public void tearDown() {
+        metaDataCache.getMetaDataMap().clear();
+        metaDataCache.getMetaDataCache().clear();
+    }
+
     @Test
     public void getInstance() {
         assertNotNull(metaDataCache);
@@ -57,4 +66,24 @@ public final class MetaDataCacheTest {
         metaDataCache.remove(this.metaData);
         assertNull(metaDataCache.obtain("/home"));
     }
+
+    @Test
+    public void testMetadataPathCacheIsBounded() {
+        for (int i = 0; i < Constants.CACHE_MAX_COUNT * 2; i++) {
+            metaDataCache.initCache("/path/" + i, metaData, 
metaData.getPath());
+        }
+
+        assertTrue(metaDataCache.getMetaDataCache().size() <= 
Constants.CACHE_MAX_COUNT);
+    }
+
+    @Test
+    public void testRemoveCleansWildcardPathEntries() {
+        MetaData wildcard = 
MetaData.builder().id("wildcard").path("/home/**").enabled(true).build();
+        metaDataCache.cache(wildcard);
+        assertNotNull(metaDataCache.obtain("/home/user/1"));
+
+        metaDataCache.remove(wildcard);
+
+        assertNull(metaDataCache.getMetaDataCache().get("/home/user/1"));
+    }
 }

Reply via email to