Skip to content

Commit

Permalink
Improve performance by inject array extension
Browse files Browse the repository at this point in the history
  • Loading branch information
hexiaofeng committed Jun 12, 2024
1 parent ca552fa commit 7e86c1e
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 32 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
* Copyright © ${year} ${owner} (${email})
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jd.live.agent.core.inject.jbind.supplier;

import com.jd.live.agent.bootstrap.classloader.ResourcerType;
import com.jd.live.agent.core.extension.ExtensibleDesc;

import java.lang.reflect.Array;
import java.util.List;

/**
* JExtensionListSourcer
*
* @since 1.0.0
*/
public class JExtensionArraySourcer extends JExtensibleSourcer {

public JExtensionArraySourcer(String name, Class<?> type, Class<?> owner, ResourcerType resourcerType) {
super(name, type, owner, resourcerType);
}

@Override
public Object getSource(Object context) {
ExtensibleDesc<?> extensible = getExtensible(context);
if (extensible == null) {
return null;
}
List<?> extensions = extensible.getExtensions();
Object result = Array.newInstance(type, extensions.size());
int index = 0;
for (Object extension : extensions) {
Array.set(result, index++, extension);
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import com.jd.live.agent.core.util.cache.CacheObject;
import com.jd.live.agent.core.util.type.FieldDesc;

import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
Expand Down Expand Up @@ -65,11 +66,13 @@ protected Sourcer createdSourcer(FieldDesc fieldDesc, String name) {
if (fieldType.equals(Publisher.class)) {
return new JPublisherSourcer(name, fieldType);
} else if (fieldType.equals(ExtensibleDesc.class)) {
return build(getExtensible(fieldDesc), name, fieldDesc, JExtensibleSourcer::new);
return build(getExtensibleByList(fieldDesc), name, fieldDesc, JExtensibleSourcer::new);
} else if (fieldType.equals(List.class)) {
return build(getExtensible(fieldDesc), name, fieldDesc, JExtensionListSourcer::new);
return build(getExtensibleByList(fieldDesc), name, fieldDesc, JExtensionListSourcer::new);
} else if (fieldType.isArray()) {
return build(getExtensibleByArray(fieldDesc), name, fieldDesc, JExtensionArraySourcer::new);
} else if (fieldType.equals(Map.class)) {
return build(getExtensibleOfMap(fieldDesc), name, fieldDesc, JExtensionMapSourcer::new);
return build(getExtensibleByMap(fieldDesc), name, fieldDesc, JExtensionMapSourcer::new);
} else if (fieldType.isInterface()) {
return build(fieldType, name, fieldDesc, JExtensionSourcer::new);
}
Expand All @@ -89,13 +92,18 @@ protected Injection createInjection(InjectType injectType, InjectionContext cont
return new JInjectAnnotationInjection(injectType);
}

protected Class<?> getExtensible(FieldDesc fieldDesc) {
Type[] types = getTypeOfArguments(fieldDesc);
protected Class<?> getExtensibleByArray(FieldDesc fieldDesc) {
Type type = getComponentType(fieldDesc);
return type instanceof Class ? (Class<?>) type : null;
}

protected Class<?> getExtensibleByList(FieldDesc fieldDesc) {
Type[] types = getParameterizedTypes(fieldDesc);
return types != null && types.length > 0 && types[0] instanceof Class ? (Class<?>) types[0] : null;
}

protected Class<?> getExtensibleOfMap(FieldDesc fieldDesc) {
Type[] types = getTypeOfArguments(fieldDesc);
protected Class<?> getExtensibleByMap(FieldDesc fieldDesc) {
Type[] types = getParameterizedTypes(fieldDesc);
if (types != null && types.length == 2 && types[0].equals(String.class)) {
if (types[1] instanceof Class<?>) {
return (Class<?>) types[1];
Expand All @@ -107,14 +115,24 @@ protected Class<?> getExtensibleOfMap(FieldDesc fieldDesc) {
return null;
}

protected Type[] getTypeOfArguments(FieldDesc fieldDesc) {
protected Type[] getParameterizedTypes(FieldDesc fieldDesc) {
Type genericType = fieldDesc.getGeneric().getType();
if (genericType instanceof ParameterizedType) {
return ((ParameterizedType) genericType).getActualTypeArguments();
}
return null;
}

protected Type getComponentType(FieldDesc fieldDesc) {
Type genericType = fieldDesc.getGeneric().getType();
if (genericType instanceof Class) {
return ((Class<?>) genericType).getComponentType();
} else if (genericType instanceof GenericArrayType) {
return ((GenericArrayType) genericType).getGenericComponentType();
}
return null;
}

@FunctionalInterface
protected interface SourcerFactory {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
import com.jd.live.agent.governance.request.ServiceRequest.InboundRequest;
import com.jd.live.agent.governance.request.ServiceRequest.OutboundRequest;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -154,43 +153,43 @@ default <R extends OutboundRequest> ClusterInvoker getClusterInvoker(OutboundInv
}

/**
* Retrieves a list of inbound filters.
* Retrieves an array of inbound filters.
* <p>
* Inbound filters are applied to requests as they are received by the service. These filters can perform
* various tasks such as logging, authentication, and request validation. The order in the list may determine
* various tasks such as logging, authentication, and request validation. The order in the array may determine
* the order in which these filters are applied.
* </p>
*
* @return A list of {@link InboundFilter} instances that are configured for the service. The list may be empty
* @return An array of {@link InboundFilter} instances that are configured for the service. The list may be empty
* if no inbound filters are configured.
*/
List<InboundFilter> getInboundFilters();
InboundFilter[] getInboundFilters();

/**
* Retrieves a list of outbound filters.
* Retrieves an array of outbound filters.
* <p>
* Outbound filters are applied to responses before they are sent back to the client. These filters can be used
* for tasks such as adding headers, transforming response bodies, or logging. Similar to inbound filters, the
* order in the list might determine the sequence in which these filters are executed.
* order in the array might determine the sequence in which these filters are executed.
* </p>
*
* @return A list of {@link OutboundFilter} instances that are configured for the service. The list may be empty
* @return An array of {@link OutboundFilter} instances that are configured for the service. The list may be empty
* if no outbound filters are configured.
*/
List<OutboundFilter> getOutboundFilters();
OutboundFilter[] getOutboundFilters();

/**
* Retrieves a list of route filters.
* Retrieves an array of route filters.
* <p>
* Route filters are used to determine how requests are routed within the service or to external services.
* They can be used for tasks such as load balancing, service discovery, and request redirection. The order
* in the list can influence the priority of routing decisions.
* in the array can influence the priority of routing decisions.
* </p>
*
* @return A list of {@link RouteFilter} instances that are used for routing decisions. The list may be empty
* @return An array of {@link RouteFilter} instances that are used for routing decisions. The list may be empty
* if no route filters are configured.
*/
List<RouteFilter> getRouteFilters();
RouteFilter[] getRouteFilters();

/**
* Processes an outbound invocation through a chain of configured outbound filters.
Expand Down Expand Up @@ -272,17 +271,17 @@ default <R extends OutboundRequest> List<? extends Endpoint> route(OutboundInvoc
* If {@code null} or empty, the default list of endpoints will be used.
* @param filters A collection of {@link RouteFilter} instances to apply to the endpoints. If
* {@code null} or empty, the default set of route filters is used.
* @return A list of {@link Endpoint} instances that have been filtered according to the
* @return An array of {@link Endpoint} instances that have been filtered according to the
* specified (or default) filters and are deemed suitable for the outbound request.
* @throws IllegalArgumentException if the invocation or any other required parameter is {@code null}.
*/
default <R extends OutboundRequest> List<? extends Endpoint> route(OutboundInvocation<R> invocation,
List<? extends Endpoint> instances,
Collection<? extends RouteFilter> filters) {
RouteFilter[] filters) {
if (instances != null && !instances.isEmpty()) {
invocation.setInstances(instances);
}
RouteFilterChain.Chain chain = new RouteFilterChain.Chain(filters == null || filters.isEmpty() ? getRouteFilters() : filters);
RouteFilterChain.Chain chain = new RouteFilterChain.Chain(filters == null || filters.length == 0 ? getRouteFilters() : filters);
chain.filter(invocation);
return invocation.getEndpoints();
}
Expand Down Expand Up @@ -371,17 +370,17 @@ public ClusterInvoker getOrDefaultClusterInvoker(String name) {
}

@Override
public List<InboundFilter> getInboundFilters() {
public InboundFilter[] getInboundFilters() {
return delegate.getInboundFilters();
}

@Override
public List<OutboundFilter> getOutboundFilters() {
public OutboundFilter[] getOutboundFilters() {
return delegate.getOutboundFilters();
}

@Override
public List<RouteFilter> getRouteFilters() {
public RouteFilter[] getRouteFilters() {
return delegate.getRouteFilters();
}

Expand Down Expand Up @@ -415,7 +414,7 @@ public <R extends OutboundRequest> List<? extends Endpoint> route(OutboundInvoca
@Override
public <R extends OutboundRequest> List<? extends Endpoint> route(OutboundInvocation<R> invocation,
List<? extends Endpoint> instances,
Collection<? extends RouteFilter> filters) {
RouteFilter[] filters) {
return delegate.route(invocation, instances, filters);
}

Expand Down Expand Up @@ -447,7 +446,7 @@ public HttpForwardContext(InvocationContext delegate) {
@Override
public <R extends OutboundRequest> List<? extends Endpoint> route(OutboundInvocation<R> invocation,
List<? extends Endpoint> instances,
Collection<? extends RouteFilter> filters) {
RouteFilter[] filters) {
List<? extends Endpoint> result = super.route(invocation, instances, filters);
if (invocation.getRequest() instanceof HttpOutboundRequest) {
HttpOutboundRequest request = (HttpOutboundRequest) invocation.getRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,17 +125,17 @@ public class PolicyManager implements PolicySupervisor, InjectSourceSupplier, Ex
@Getter
@Inject
@InjectLoader(ResourcerType.CORE_IMPL)
private List<InboundFilter> inboundFilters;
private InboundFilter[] inboundFilters;

@Getter
@Inject
@InjectLoader(ResourcerType.CORE_IMPL)
private List<OutboundFilter> outboundFilters;
private OutboundFilter[] outboundFilters;

@Getter
@Inject
@InjectLoader(ResourcerType.CORE_IMPL)
private List<RouteFilter> routeFilters;
private RouteFilter[] routeFilters;

@Inject(ServiceSupervisor.COMPONENT_SERVICE_SUPERVISOR)
private ServiceSupervisor serviceSupervisor;
Expand Down

0 comments on commit 7e86c1e

Please sign in to comment.