BitoAgent commented on code in PR #13786: URL: https://github.com/apache/dubbo/pull/13786#discussion_r1543381792
########## 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 { ... } ... } ``` ########## 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]); ``` -- 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: notifications-unsubscr...@dubbo.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: notifications-unsubscr...@dubbo.apache.org For additional commands, e-mail: notifications-h...@dubbo.apache.org