HDDS-14922. Define ScmInvoker#invokeRatisServer to proxy DeletedBlockLogStateManager without reflection#10013
Conversation
|
Hi @szetszwo, could you please review this PR when you have time? Thank you! |
There was a problem hiding this comment.
@Russole , thanks for working on this! We should not use Proxy.newProxyInstance(..) anymore; see https://issues.apache.org/jira/secure/attachment/13081517/10013_review.patch
| if (invoker != null) { | ||
| return invoker.invokeRatisServer( | ||
| method.getName(), method.getParameterTypes(), args); | ||
| } |
There was a problem hiding this comment.
This change does not help since it is after the proxy. We should do it before the proxy.
|
Thanks @szetszwo for the review. Updated the implementation to handle overloaded |
szetszwo
left a comment
There was a problem hiding this comment.
... Without this, incorrect overload resolution could lead to null ...
@Russole , Good catch on the bug!
Please see the comments inlined and also https://issues.apache.org/jira/secure/attachment/13081552/10013_review2.patch
| LOG.trace("Invoking method {} on target {} with arguments {}", | ||
| method, localHandler, args); | ||
| } | ||
| Preconditions.assertNull(invoker, "invoker"); |
There was a problem hiding this comment.
The invoker field is always null. We should remove it.
| if (invoker != null) { | ||
| return invoker.getProxy(); | ||
| } |
There was a problem hiding this comment.
We don't need the common method anymore.
default <T> T getProxyHandler(ScmInvoker<T> invoker) {
registerStateMachineHandler(invoker.getType(), invoker.getImpl());
return invoker.getProxy();
}
default <T> T getProxyHandler(RequestType type, Class<T> intf, T impl) {
final SCMHAInvocationHandler invocationHandler =
new SCMHAInvocationHandler(type, impl, this);
return intf.cast(Proxy.newProxyInstance(getClass().getClassLoader(),
new Class<?>[] {intf}, invocationHandler));
}| } | ||
|
|
||
| @Override | ||
| protected Class<?>[] getParameterTypes(String methodName) { |
There was a problem hiding this comment.
Let's add an enum instead:
enum ReplicateMethod implements NameAndParameterTypes {
addTransactionsToDB(new Class<?>[] {ArrayList.class, DeletedBlocksTransactionSummary.class}),
removeTransactionsFromDB(new Class<?>[] {ArrayList.class, DeletedBlocksTransactionSummary.class}),
;
private final Class<?>[][] parameterTypes;
ReplicateMethod(Class<?>[] parameterTypes) {
final Class<?>[][] types = new Class<?>[parameterTypes.length + 1][];
for(int i = 0; i <= parameterTypes.length; ++i) {
types[i] = Arrays.copyOf(parameterTypes, i);
}
this.parameterTypes = types;
}
@Override
public String getName() {
return name();
}
@Override
public Class<?>[] getParameterTypes(int numArgs) {
return parameterTypes[numArgs];
}
}| Object invokeRatisServer(String methodName, Class<?>[] paramTypes, | ||
| Object[] args) throws SCMException { |
There was a problem hiding this comment.
Let's add an interface:
interface NameAndParameterTypes {
String getName();
Class<?>[] getParameterTypes(int numArgs);
} Object invokeRatisServer(NameAndParameterTypes method, Object[] args) throws SCMException {
try {
final SCMRatisRequest request = SCMRatisRequest.of(
getType(), method.getName(), method.getParameterTypes(args.length), args);
szetszwo
left a comment
There was a problem hiding this comment.
+1 the change looks good.
What changes were proposed in this pull request?
invokeRatisServer(..)toScmInvokerto centralize Ratis server invocation logicSCMHAInvocationHandlertoScmInvokerSCMHAInvocationHandlerto delegateDIRECTinvocation toScmInvokerScmInvokeris not available (for backward compatibility)DeletedBlockLogStateManagerFollow-up
DeletedBlockLogStateManagerfirst; other SCM handlers will be updated in follow-up patchesWhat is the link to the Apache JIRA
https://issues.apache.org/jira/browse/HDDS-14922
How was this patch tested?