ruanwenjun commented on code in PR #14797:
URL: 
https://github.com/apache/dolphinscheduler/pull/14797#discussion_r1304475784


##########
dolphinscheduler-extract/dolphinscheduler-extract-base/src/main/java/org/apache/dolphinscheduler/extract/base/client/JdkDynamicRpcClientProxyFactory.java:
##########
@@ -21,31 +21,44 @@
 import org.apache.dolphinscheduler.extract.base.utils.Host;
 
 import java.lang.reflect.Proxy;
+import java.time.Duration;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
+import lombok.SneakyThrows;
+
+import com.google.common.cache.Cache;
+import com.google.common.cache.CacheBuilder;
+
 /**
  * This class is used to create a proxy client which will transform local 
method invocation to remove invocation.
  */
 public class JdkDynamicRpcClientProxyFactory implements IRpcClientProxyFactory 
{
 
     private final NettyRemotingClient nettyRemotingClient;
 
-    // todo: use guava cache to avoid memory leak
-    private final Map<String, Map<String, Object>> proxyClientCache = new 
ConcurrentHashMap<>();
+    private final Cache<String, Map<String, Object>> proxyClientCache = 
CacheBuilder.newBuilder()
+            // expire here to remove dead host
+            .expireAfterAccess(Duration.ofHours(1))
+            .build();
 
     public JdkDynamicRpcClientProxyFactory(NettyRemotingClient 
nettyRemotingClient) {
         this.nettyRemotingClient = nettyRemotingClient;
     }
 
+    @SneakyThrows
     @SuppressWarnings("unchecked")
     @Override
     public <T> T getProxyClient(String serverHost, Class<T> clientInterface) {
-        return (T) proxyClientCache
-                .computeIfAbsent(serverHost, key -> new ConcurrentHashMap<>())
-                .computeIfAbsent(clientInterface.getName(),
-                        key -> Proxy.newProxyInstance(
-                                clientInterface.getClassLoader(), new 
Class[]{clientInterface},
-                                new 
ClientInvocationHandler(Host.of(serverHost), nettyRemotingClient)));
+        return (T) proxyClientCache.get(serverHost, ConcurrentHashMap::new)

Review Comment:
   Thanks for reminding me of this, I tested this, and this should work well.
   
   Go deep into the code, 
   ```java
   V get(K key, Callable<? extends V> loader) throws ExecutionException;
   ```
   I find the doc might means if you have the same keys with different loader, 
e.g
   ```
   cache.get("key", loader1);
   cache.get("key", loader2);
   ```
   and the two methods occur in two threads, the return value is unknown, since 
the return value is related to the loader, the first method might return the 
value of loader2, but if we use LoadingCache, the return value is known, since 
there is only one loader, the loader is not expose to the get method.
   
   Anyway I changed to LoadingCache, it's safer.



-- 
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]

Reply via email to