BitoAgent commented on code in PR #13786:
URL: https://github.com/apache/dubbo/pull/13786#discussion_r1543381768


##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -221,7 +221,7 @@ public AbstractInterfaceConfig(ModuleModel moduleModel) {
     /**
      * The url of the reference service
      */
-    protected final transient List<URL> urls = new ArrayList<URL>();
+    protected final transient List<URL> urls = new ArrayList<>();

Review Comment:
    **Suggestion**: Utilize the diamond operator for initializing the ArrayList 
to improve code readability. <br> **Code Suggestion**: 
    ```
    +    protected final transient List<URL> urls = new ArrayList<>();
    ```
   
   



##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -353,14 +353,14 @@
 
             // refresh MethodConfigs
             List<MethodConfig> methodConfigs = this.getMethods();
-            if (methodConfigs != null && methodConfigs.size() > 0) {
+            if (methodConfigs != null && !methodConfigs.isEmpty()) {

Review Comment:
    **Suggestion**: Replace size() > 0 check with !isEmpty() for clarity and 
performance. <br> **Code Suggestion**: 
    ```
    +            if (methodConfigs != null && !methodConfigs.isEmpty()) {
    ```
   
   



##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -252,7 +252,7 @@
         }
         if (CollectionUtils.isNotEmpty(this.registries)) {
             this.registries.forEach(registryConfig -> {
-                if (registryConfig.getScopeModel() != applicationModel) {
+                if (registryConfig != null && registryConfig.getScopeModel() 
!= applicationModel) {

Review Comment:
    **Suggestion**: Add null check for registryConfig to avoid potential 
NullPointerException. <br> **Code Suggestion**: 
    ```
    +                if (registryConfig != null && 
registryConfig.getScopeModel() != applicationModel) {
    ```
   
   



##########
dubbo-remoting/dubbo-remoting-http12/src/main/java/org/apache/dubbo/remoting/http12/message/LengthFieldStreamingDecoder.java:
##########
@@ -20,7 +20,6 @@
 import org.apache.dubbo.remoting.http12.exception.DecodeException;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;

Review Comment:
    **Performance Issue**: Unused import 'java.io.ByteArrayOutputStream' should 
be removed to keep code clean. <br> **Fix**: Remove the unused import statement 
to clean up the code. <br> **Code Suggestion**: 
    ```
    -import java.io.ByteArrayOutputStream;
    ```
   
   



##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -353,14 +353,14 @@
 
             // refresh MethodConfigs
             List<MethodConfig> methodConfigs = this.getMethods();
-            if (methodConfigs != null && methodConfigs.size() > 0) {
+            if (methodConfigs != null && !methodConfigs.isEmpty()) {

Review Comment:
    **Optimization Issue**: Replacing 'methodConfigs.size() > 0' with 
'!methodConfigs.isEmpty()' improves readability and is more idiomatic. <br> 
**Fix**: Use '!methodConfigs.isEmpty()' to check if the list is not empty, 
which is more direct and readable. <br> **Code Suggestion**: 
    ```
    -            if (methods != null && methods.size() > 0) {
    +            if (methods != null && !methods.isEmpty()) {
    ```
   
   



##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -420,7 +420,7 @@
     }
 
     private ArgumentConfig getArgumentByIndex(MethodConfig methodConfig, int 
argIndex) {
-        if (methodConfig.getArguments() != null && 
methodConfig.getArguments().size() > 0) {
+        if (methodConfig.getArguments() != null && 
!methodConfig.getArguments().isEmpty()) {

Review Comment:
    **Suggestion**: Simplify collection emptiness check using !isEmpty(). <br> 
**Code Suggestion**: 
    ```
    +        if (methodConfig.getArguments() != null && 
!methodConfig.getArguments().isEmpty()) {
    ```
   
   



##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -252,7 +252,7 @@
         }
         if (CollectionUtils.isNotEmpty(this.registries)) {
             this.registries.forEach(registryConfig -> {
-                if (registryConfig.getScopeModel() != applicationModel) {
+                if (registryConfig != null && registryConfig.getScopeModel() 
!= applicationModel) {

Review Comment:
    **Performance Issue**: Adding null check for 'registryConfig' before 
accessing its methods prevents potential 'NullPointerException'. <br> **Fix**: 
Add a null check for 'registryConfig' to ensure safety when accessing its 
'getScopeModel' method. <br> **Code Suggestion**: 
    ```
    -                if (registryConfig.getScopeModel() != applicationModel) {
    +                if (registryConfig != null && 
registryConfig.getScopeModel() != applicationModel) {
    ```
   
   



##########
dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/h12/grpc/GrpcCompositeCodec.java:
##########
@@ -16,123 +16,103 @@
  */
 package org.apache.dubbo.rpc.protocol.tri.h12.grpc;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.ConfigurationUtils;
+import org.apache.dubbo.common.io.StreamUtils;
+import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.remoting.http12.exception.DecodeException;
 import org.apache.dubbo.remoting.http12.exception.EncodeException;
 import org.apache.dubbo.remoting.http12.message.HttpMessageCodec;
 import org.apache.dubbo.remoting.http12.message.MediaType;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.MethodDescriptor;
+import org.apache.dubbo.rpc.model.PackableMethod;
+import org.apache.dubbo.rpc.model.PackableMethodFactory;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
-import com.google.protobuf.Message;
-
-import static 
org.apache.dubbo.common.constants.CommonConstants.PROTOBUF_MESSAGE_CLASS_NAME;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
+import static 
org.apache.dubbo.common.constants.CommonConstants.DUBBO_PACKABLE_METHOD_FACTORY;
 
 public class GrpcCompositeCodec implements HttpMessageCodec {
 
-    private final ProtobufHttpMessageCodec protobufHttpMessageCodec;
+    private static final String PACKABLE_METHOD_CACHE = 
"PACKABLE_METHOD_CACHE";
 
-    private final WrapperHttpMessageCodec wrapperHttpMessageCodec;
+    private final URL url;
 
-    public GrpcCompositeCodec(
-            ProtobufHttpMessageCodec protobufHttpMessageCodec, 
WrapperHttpMessageCodec wrapperHttpMessageCodec) {
-        this.protobufHttpMessageCodec = protobufHttpMessageCodec;
-        this.wrapperHttpMessageCodec = wrapperHttpMessageCodec;
-    }
+    private final FrameworkModel frameworkModel;
+
+    private final String mediaType;
 
-    public void setEncodeTypes(Class<?>[] encodeTypes) {
-        this.wrapperHttpMessageCodec.setEncodeTypes(encodeTypes);
+    private PackableMethod packableMethod;
+
+    public GrpcCompositeCodec(URL url, FrameworkModel frameworkModel, String 
mediaType) {
+        this.url = url;
+        this.frameworkModel = frameworkModel;
+        this.mediaType = mediaType;
     }
 
-    public void setDecodeTypes(Class<?>[] decodeTypes) {
-        this.wrapperHttpMessageCodec.setDecodeTypes(decodeTypes);
+    public void loadPackableMethod(MethodDescriptor methodDescriptor) {
+        if (methodDescriptor instanceof PackableMethod) {
+            packableMethod = (PackableMethod) methodDescriptor;
+            return;
+        }
+        Map<MethodDescriptor, PackableMethod> cacheMap = 
(Map<MethodDescriptor, PackableMethod>) url.getServiceModel()
+                .getServiceMetadata()
+                .getAttributeMap()
+                .computeIfAbsent(PACKABLE_METHOD_CACHE, k -> new 
ConcurrentHashMap<>());
+        packableMethod = cacheMap.computeIfAbsent(methodDescriptor, md -> 
frameworkModel
+                .getExtensionLoader(PackableMethodFactory.class)
+                
.getExtension(ConfigurationUtils.getGlobalConfiguration(url.getApplicationModel())
+                        .getString(DUBBO_PACKABLE_METHOD_FACTORY, DEFAULT_KEY))
+                .create(methodDescriptor, url, mediaType));
     }
 
     @Override
     public void encode(OutputStream outputStream, Object data, Charset 
charset) throws EncodeException {
-        // protobuf
-        // TODO int compressed = 
Identity.MESSAGE_ENCODING.equals(requestMetadata.compressor.getMessageEncoding())
 ? 0 :
-        // 1;
         try {
-            int compressed = 0;
-            outputStream.write(compressed);
-            if (isProtobuf(data)) {
-                ProtobufWriter.write(protobufHttpMessageCodec, outputStream, 
data);
-                return;
-            }
-            // wrapper
-            wrapperHttpMessageCodec.encode(outputStream, data);
-        } catch (IOException e) {
+            outputStream.write(0);
+            byte[] bytes = packableMethod.packResponse(data);
+            writeLength(outputStream, bytes.length);
+            outputStream.write(bytes);
+        } catch (Exception e) {
             throw new EncodeException(e);
         }
     }
 
     @Override
     public Object decode(InputStream inputStream, Class<?> targetType, Charset 
charset) throws DecodeException {
-        if (isProtoClass(targetType)) {
-            return protobufHttpMessageCodec.decode(inputStream, targetType, 
charset);
+        try {
+            byte[] data = StreamUtils.readBytes(inputStream);
+            return packableMethod.parseRequest(data);
+        } catch (Exception e) {
+            throw new DecodeException(e);
         }
-        return wrapperHttpMessageCodec.decode(inputStream, targetType, 
charset);
     }
 
     @Override
     public Object[] decode(InputStream inputStream, Class<?>[] targetTypes, 
Charset charset) throws DecodeException {
-        if (targetTypes.length > 1) {
-            return wrapperHttpMessageCodec.decode(inputStream, targetTypes, 
charset);
-        }
-        return HttpMessageCodec.super.decode(inputStream, targetTypes, 
charset);
-    }
-
-    private static void writeLength(OutputStream outputStream, int length) {
-        try {
-            outputStream.write(((length >> 24) & 0xFF));
-            outputStream.write(((length >> 16) & 0xFF));
-            outputStream.write(((length >> 8) & 0xFF));
-            outputStream.write((length & 0xFF));
-        } catch (IOException e) {
-            throw new EncodeException(e);
+        Object message = decode(inputStream, ArrayUtils.isEmpty(targetTypes) ? 
null : targetTypes[0], charset);
+        if (message instanceof Object[]) {
+            return (Object[]) message;
         }
+        return new Object[] {message};
     }
 
     @Override
     public MediaType mediaType() {
         return MediaType.APPLICATION_GRPC;
     }
 
-    private static boolean isProtobuf(Object data) {
-        if (data == null) {
-            return false;
-        }
-        return isProtoClass(data.getClass());
-    }
-
-    private static boolean isProtoClass(Class<?> clazz) {
-        while (clazz != Object.class && clazz != null) {
-            Class<?>[] interfaces = clazz.getInterfaces();
-            if (interfaces.length > 0) {
-                for (Class<?> clazzInterface : interfaces) {
-                    if 
(PROTOBUF_MESSAGE_CLASS_NAME.equalsIgnoreCase(clazzInterface.getName())) {
-                        return true;
-                    }
-                }
-            }
-            clazz = clazz.getSuperclass();
-        }
-        return false;
-    }
-
-    /**
-     * lazy init protobuf class
-     */
-    private static class ProtobufWriter {
-
-        private static void write(HttpMessageCodec codec, OutputStream 
outputStream, Object data) {
-            int serializedSize = ((Message) data).getSerializedSize();
-            // write length
-            writeLength(outputStream, serializedSize);
-            codec.encode(outputStream, data);
-        }
+    private void writeLength(OutputStream outputStream, int length) throws 
IOException {
+        outputStream.write(((length >> 24) & 0xFF));
+        outputStream.write(((length >> 16) & 0xFF));
+        outputStream.write(((length >> 8) & 0xFF));
+        outputStream.write((length & 0xFF));

Review Comment:
    **Suggestion**: Implement writeLength method directly in GrpcCompositeCodec 
to encapsulate byte length writing logic. <br> **Code Suggestion**: 
    ```
    +        outputStream.write(((length >> 24) & 0xFF));
    +        outputStream.write(((length >> 16) & 0xFF));
    +        outputStream.write(((length >> 8) & 0xFF));
    +        outputStream.write((length & 0xFF));
    ```
   
   



##########
dubbo-remoting/dubbo-remoting-http12/src/main/java/org/apache/dubbo/remoting/http12/message/LengthFieldStreamingDecoder.java:
##########
@@ -46,8 +45,6 @@
 
     private int requiredLength;
 
-    private InputStream dataHeader = new ByteArrayInputStream(new byte[0]);
-
     public LengthFieldStreamingDecoder() {
         this(4);
     }

Review Comment:
    **Performance Issue**: The 'dataHeader' InputStream field is declared but 
never used in the 'LengthFieldStreamingDecoder' class. Unused fields can lead 
to confusion and should be removed if they are not planned to be used. <br> 
**Fix**: Remove the 'dataHeader' field as it is not used anywhere in the class. 
<br> **Code Suggestion**: 
    ```
    -    private InputStream dataHeader = new ByteArrayInputStream(new byte[0]);
    ```
   
   



##########
dubbo-remoting/dubbo-remoting-http12/src/main/java/org/apache/dubbo/remoting/http12/message/LengthFieldStreamingDecoder.java:
##########
@@ -20,7 +20,6 @@
 import org.apache.dubbo.remoting.http12.exception.DecodeException;
 
 import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
 import java.io.IOException;

Review Comment:
    **Suggestion**: Remove unused import to clean up the code. <br> **Code 
Suggestion**: 
    ```
    (Removal, no replacement needed)
    ```
   
   



##########
dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/h12/grpc/GrpcCompositeCodec.java:
##########
@@ -16,123 +16,103 @@
  */
 package org.apache.dubbo.rpc.protocol.tri.h12.grpc;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.ConfigurationUtils;
+import org.apache.dubbo.common.io.StreamUtils;
+import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.remoting.http12.exception.DecodeException;
 import org.apache.dubbo.remoting.http12.exception.EncodeException;
 import org.apache.dubbo.remoting.http12.message.HttpMessageCodec;
 import org.apache.dubbo.remoting.http12.message.MediaType;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.MethodDescriptor;
+import org.apache.dubbo.rpc.model.PackableMethod;
+import org.apache.dubbo.rpc.model.PackableMethodFactory;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
-import com.google.protobuf.Message;
-
-import static 
org.apache.dubbo.common.constants.CommonConstants.PROTOBUF_MESSAGE_CLASS_NAME;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
+import static 
org.apache.dubbo.common.constants.CommonConstants.DUBBO_PACKABLE_METHOD_FACTORY;
 
 public class GrpcCompositeCodec implements HttpMessageCodec {
 
-    private final ProtobufHttpMessageCodec protobufHttpMessageCodec;
+    private static final String PACKABLE_METHOD_CACHE = 
"PACKABLE_METHOD_CACHE";
 
-    private final WrapperHttpMessageCodec wrapperHttpMessageCodec;
+    private final URL url;
 
-    public GrpcCompositeCodec(
-            ProtobufHttpMessageCodec protobufHttpMessageCodec, 
WrapperHttpMessageCodec wrapperHttpMessageCodec) {
-        this.protobufHttpMessageCodec = protobufHttpMessageCodec;
-        this.wrapperHttpMessageCodec = wrapperHttpMessageCodec;
-    }
+    private final FrameworkModel frameworkModel;
+
+    private final String mediaType;
 
-    public void setEncodeTypes(Class<?>[] encodeTypes) {
-        this.wrapperHttpMessageCodec.setEncodeTypes(encodeTypes);
+    private PackableMethod packableMethod;
+
+    public GrpcCompositeCodec(URL url, FrameworkModel frameworkModel, String 
mediaType) {
+        this.url = url;
+        this.frameworkModel = frameworkModel;
+        this.mediaType = mediaType;
     }
 
-    public void setDecodeTypes(Class<?>[] decodeTypes) {
-        this.wrapperHttpMessageCodec.setDecodeTypes(decodeTypes);
+    public void loadPackableMethod(MethodDescriptor methodDescriptor) {
+        if (methodDescriptor instanceof PackableMethod) {
+            packableMethod = (PackableMethod) methodDescriptor;
+            return;
+        }
+        Map<MethodDescriptor, PackableMethod> cacheMap = 
(Map<MethodDescriptor, PackableMethod>) url.getServiceModel()
+                .getServiceMetadata()
+                .getAttributeMap()
+                .computeIfAbsent(PACKABLE_METHOD_CACHE, k -> new 
ConcurrentHashMap<>());
+        packableMethod = cacheMap.computeIfAbsent(methodDescriptor, md -> 
frameworkModel
+                .getExtensionLoader(PackableMethodFactory.class)
+                
.getExtension(ConfigurationUtils.getGlobalConfiguration(url.getApplicationModel())
+                        .getString(DUBBO_PACKABLE_METHOD_FACTORY, DEFAULT_KEY))
+                .create(methodDescriptor, url, mediaType));

Review Comment:
    **Optimization Issue**: Simplification of codec creation logic by directly 
initializing GrpcCompositeCodec with necessary parameters instead of managing 
separate codec instances. <br> **Fix**: Refactor the codec creation to use a 
single GrpcCompositeCodec instance, simplifying the overall design and 
improving maintainability. <br> **Code Suggestion**: 
    ```
    public class GrpcCompositeCodec implements HttpMessageCodec {
   
        private final URL url;
   
        private final FrameworkModel frameworkModel;
   
        private final String mediaType;
   
        private PackableMethod packableMethod;
   
        public GrpcCompositeCodec(URL url, FrameworkModel frameworkModel, 
String mediaType) {
            this.url = url;
            this.frameworkModel = frameworkModel;
            this.mediaType = mediaType;
            initialize();
        }
   
        private void initialize() {
            // Initialization logic here
        }
   
        @Override
        public void encode(OutputStream outputStream, Object data, Charset 
charset) throws EncodeException {
            ...
        }
   
        @Override
        public Object decode(InputStream inputStream, Class<?> targetType, 
Charset charset) throws DecodeException {
            ...
        }
   
        ...
    }
    ```
   
   



##########
dubbo-common/src/main/java/org/apache/dubbo/config/AbstractInterfaceConfig.java:
##########
@@ -252,7 +252,7 @@
         }
         if (CollectionUtils.isNotEmpty(this.registries)) {
             this.registries.forEach(registryConfig -> {
-                if (registryConfig.getScopeModel() != applicationModel) {
+                if (registryConfig != null && registryConfig.getScopeModel() 
!= applicationModel) {

Review Comment:
    **Scalability Issue**: Adding a null check ('registryConfig != null') 
before checking the scope model increases the robustness of the code. This 
change prevents potential NullPointerExceptions, which can be critical in a 
scalable system where registry configurations might be dynamically loaded or 
unloaded, leading to situations where 'registryConfig' could be 'null'. <br> 
**Fix**: The addition of the null check is a good practice. Ensure that all 
similar instances in the codebase are also checked for null to maintain 
consistency and prevent scalability issues related to dynamic configuration 
changes. <br> **Code Suggestion**: 
    ```
    The addition of the null check is a good practice. Ensure that all similar 
instances in the codebase are also checked for null to maintain consistency and 
prevent scalability issues related to dynamic configuration changes.
    ```
   
   



##########
dubbo-rpc/dubbo-rpc-triple/src/main/java/org/apache/dubbo/rpc/protocol/tri/h12/grpc/GrpcCompositeCodec.java:
##########
@@ -16,123 +16,103 @@
  */
 package org.apache.dubbo.rpc.protocol.tri.h12.grpc;
 
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.config.ConfigurationUtils;
+import org.apache.dubbo.common.io.StreamUtils;
+import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.remoting.http12.exception.DecodeException;
 import org.apache.dubbo.remoting.http12.exception.EncodeException;
 import org.apache.dubbo.remoting.http12.message.HttpMessageCodec;
 import org.apache.dubbo.remoting.http12.message.MediaType;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+import org.apache.dubbo.rpc.model.MethodDescriptor;
+import org.apache.dubbo.rpc.model.PackableMethod;
+import org.apache.dubbo.rpc.model.PackableMethodFactory;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.charset.Charset;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 
-import com.google.protobuf.Message;
-
-import static 
org.apache.dubbo.common.constants.CommonConstants.PROTOBUF_MESSAGE_CLASS_NAME;
+import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY;
+import static 
org.apache.dubbo.common.constants.CommonConstants.DUBBO_PACKABLE_METHOD_FACTORY;
 
 public class GrpcCompositeCodec implements HttpMessageCodec {
 
-    private final ProtobufHttpMessageCodec protobufHttpMessageCodec;
+    private static final String PACKABLE_METHOD_CACHE = 
"PACKABLE_METHOD_CACHE";
 
-    private final WrapperHttpMessageCodec wrapperHttpMessageCodec;
+    private final URL url;
 
-    public GrpcCompositeCodec(
-            ProtobufHttpMessageCodec protobufHttpMessageCodec, 
WrapperHttpMessageCodec wrapperHttpMessageCodec) {
-        this.protobufHttpMessageCodec = protobufHttpMessageCodec;
-        this.wrapperHttpMessageCodec = wrapperHttpMessageCodec;
-    }
+    private final FrameworkModel frameworkModel;
+
+    private final String mediaType;
 
-    public void setEncodeTypes(Class<?>[] encodeTypes) {
-        this.wrapperHttpMessageCodec.setEncodeTypes(encodeTypes);
+    private PackableMethod packableMethod;
+
+    public GrpcCompositeCodec(URL url, FrameworkModel frameworkModel, String 
mediaType) {
+        this.url = url;
+        this.frameworkModel = frameworkModel;
+        this.mediaType = mediaType;
     }
 
-    public void setDecodeTypes(Class<?>[] decodeTypes) {
-        this.wrapperHttpMessageCodec.setDecodeTypes(decodeTypes);
+    public void loadPackableMethod(MethodDescriptor methodDescriptor) {
+        if (methodDescriptor instanceof PackableMethod) {
+            packableMethod = (PackableMethod) methodDescriptor;
+            return;
+        }
+        Map<MethodDescriptor, PackableMethod> cacheMap = 
(Map<MethodDescriptor, PackableMethod>) url.getServiceModel()
+                .getServiceMetadata()
+                .getAttributeMap()
+                .computeIfAbsent(PACKABLE_METHOD_CACHE, k -> new 
ConcurrentHashMap<>());
+        packableMethod = cacheMap.computeIfAbsent(methodDescriptor, md -> 
frameworkModel
+                .getExtensionLoader(PackableMethodFactory.class)
+                
.getExtension(ConfigurationUtils.getGlobalConfiguration(url.getApplicationModel())
+                        .getString(DUBBO_PACKABLE_METHOD_FACTORY, DEFAULT_KEY))
+                .create(methodDescriptor, url, mediaType));
     }
 
     @Override
     public void encode(OutputStream outputStream, Object data, Charset 
charset) throws EncodeException {
-        // protobuf
-        // TODO int compressed = 
Identity.MESSAGE_ENCODING.equals(requestMetadata.compressor.getMessageEncoding())
 ? 0 :
-        // 1;
         try {
-            int compressed = 0;
-            outputStream.write(compressed);
-            if (isProtobuf(data)) {
-                ProtobufWriter.write(protobufHttpMessageCodec, outputStream, 
data);
-                return;
-            }
-            // wrapper
-            wrapperHttpMessageCodec.encode(outputStream, data);
-        } catch (IOException e) {
+            outputStream.write(0);
+            byte[] bytes = packableMethod.packResponse(data);
+            writeLength(outputStream, bytes.length);
+            outputStream.write(bytes);

Review Comment:
    **Scalability Issue**: Refactoring to use a more modular and extensible 
codec system, such as replacing specific codec implementations with a more 
generic, pluggable mechanism, can significantly enhance the scalability of the 
system. This allows for easier addition of new codecs and serialization 
mechanisms without modifying the core logic, which is crucial for maintaining a 
scalable, extensible system. <br> **Fix**: Implement a codec registry or 
factory pattern that allows for runtime registration and retrieval of codecs. 
This pattern should support lazy loading and initialization of codecs to 
minimize startup time and memory footprint, enhancing the scalability of the 
system. <br> **Code Suggestion**: 
    ```
    public class GrpcCompositeCodec implements HttpMessageCodec {
   
        private final URL url;
   
        private final FrameworkModel frameworkModel;
   
        private final String mediaType;
   
        private PackableMethod packableMethod;
   
        private static final Map<MethodDescriptor, PackableMethod> cacheMap = 
new ConcurrentHashMap<>();
   
        public GrpcCompositeCodec(URL url, FrameworkModel frameworkModel, 
String mediaType) {
            this.url = url;
            this.frameworkModel = frameworkModel;
            this.mediaType = mediaType;
        }
   
        public void loadPackableMethod(MethodDescriptor methodDescriptor) {
            packableMethod = cacheMap.computeIfAbsent(methodDescriptor, md -> 
frameworkModel
                    .getExtensionLoader(PackableMethodFactory.class)
                    
.getExtension(ConfigurationUtils.getGlobalConfiguration(url.getApplicationModel())
                            .getString(DUBBO_PACKABLE_METHOD_FACTORY, 
DEFAULT_KEY))
                    .create(methodDescriptor, url, mediaType));
        }
   
        @Override
        public void encode(OutputStream outputStream, Object data, Charset 
charset) throws EncodeException {
            ...
        }
   
        @Override
        public Object decode(InputStream inputStream, Class<?> targetType, 
Charset charset) throws DecodeException {
            ...
        }
   
        ...
    }
    ```
   
   



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


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to