Skip to content

fix Dubbo3.x Context problem #8525#110

Merged
wu-sheng merged 12 commits intoapache:mainfrom
honganan:dubbo3_context_fix
Feb 25, 2022
Merged

fix Dubbo3.x Context problem #8525#110
wu-sheng merged 12 commits intoapache:mainfrom
honganan:dubbo3_context_fix

Conversation

@honganan
Copy link
Copy Markdown
Contributor

@honganan honganan commented Feb 11, 2022

  • If this pull request closes/resolves/fixes an existing issue, replace the issue number. Closes #8525.
  • Update the CHANGES log.

Comment on lines +148 to +150
return invoker.getUrl()
.getParameter("side", "consumer")
.equals("provider");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this an official way? It seems strange. I am waiting for Dubbo team to response.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can wait for the Dubbo team...
I write this from my understanding to the scope of Rpc*Context and RpcInvocation.
The RpcServiceContext#isConsumerSide() implements like:

public boolean isConsumerSide() {
        return this.getUrl().getSide("provider").equals("consumer");
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is already official, could we use RpcServiceContext#isConsumerSide() directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is RpcServiceContext not been reset when it's role switched, but RpcInvocation is always correctly bounded to the current request or serve request

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see. Could you add this as comments on the codes? This is important to keep this in mind why we change now.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, same as I see. I will modify it and pass the test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we just need to declare the parent class only.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But I can't see the link from your comments, but the conclusion is certain.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#73 (comment)
I reduced 2 Instrumentation to 1 and testing it.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Let's see.

@wu-sheng wu-sheng added plugin enhancement New feature or request labels Feb 11, 2022
@wu-sheng
Copy link
Copy Markdown
Member

@honganan Could you make this PR works? I am not sure why Dubbocommunity seems not responsing. Let's try at our side.

@wu-sheng
Copy link
Copy Markdown
Member

@honganan Any update?

Comment on lines -114 to -116
if (result != null && result.getException() != null) {
dealException(result.getException());
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to process result#getExcetpion?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't received notifications these days, I will debug and make it clear about how it process Exceptions.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually, we don't need to catch exceptions, as the handleMethodException method exists already. But we should process result#getExcetpion, because this exception may throw after the whole intercepting is finished or even wouldn't, depending on Dubbo's implementation.

@honganan
Copy link
Copy Markdown
Contributor Author

I can, in these two days. I need more time to make it clear how Dubbo handle exception.

@wu-sheng
Copy link
Copy Markdown
Member

Error:  testConsumerWithException(org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest)  Time elapsed: 2.085 s  <<< ERROR!
java.lang.NullPointerException
	at org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest.testConsumerWithException(DubboInterceptorTest.java:156)

Error:  testConsumerWithResultHasException(org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest)  Time elapsed: 0.013 s  <<< ERROR!
java.lang.NullPointerException
	at org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest.testConsumerWithResultHasException(DubboInterceptorTest.java:169)

Error:  testConsumerWithAttachment(org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest)  Time elapsed: 0.008 s  <<< ERROR!
java.lang.NullPointerException
	at org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest.testConsumerWithAttachment(DubboInterceptorTest.java:144)

@honganan I think you missed some UTs.

Copy link
Copy Markdown
Member

@wu-sheng wu-sheng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

UT fails, pending.

@honganan
Copy link
Copy Markdown
Contributor Author

honganan commented Feb 24, 2022 via email

@wu-sheng
Copy link
Copy Markdown
Member

I think this mock preparation is not enough, should be enhanced with the URL you expect.

@honganan
Copy link
Copy Markdown
Contributor Author

I think this mock preparation is not enough, should be enhanced with the URL you expect.

Do you mean add clean side param in the URL in DubboInterceptorTest?

@honganan
Copy link
Copy Markdown
Contributor Author

It's strange the Unit Test fails with NPE, unless @Before annotated method not invoked. Can you help me check code of DubboInterceptorTest

@wu-sheng
Copy link
Copy Markdown
Member

image

I can't see you mocked the attachment in prepare stage. Only testProviderWithAttachment method has this.

This is easy to reproduce locally.

java.lang.NullPointerException
	at org.apache.skywalking.apm.plugin.asf.dubbo3.DubboInterceptor.beforeMethod(DubboInterceptor.java:99)
	at org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest.testConsumerWithException(DubboInterceptorTest.java:156)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner$1.evaluate(TracingSegmentRunner.java:85)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:149)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:141)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.withContextClassLoader(DelegatingPowerMockRunner.java:132)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:141)

@honganan
Copy link
Copy Markdown
Contributor Author

image

I can't see you mocked the attachment in prepare stage. Only testProviderWithAttachment method has this.

This is easy to reproduce locally.

java.lang.NullPointerException
	at org.apache.skywalking.apm.plugin.asf.dubbo3.DubboInterceptor.beforeMethod(DubboInterceptor.java:99)
	at org.apache.skywalking.apm.plugin.dubbo3.DubboInterceptorTest.testConsumerWithException(DubboInterceptorTest.java:156)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
	at org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner$1.evaluate(TracingSegmentRunner.java:85)
	at org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48)
	at org.junit.rules.RunRules.evaluate(RunRules.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:149)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner$2.call(DelegatingPowerMockRunner.java:141)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.withContextClassLoader(DelegatingPowerMockRunner.java:132)
	at org.powermock.modules.junit4.internal.impl.DelegatingPowerMockRunner.run(DelegatingPowerMockRunner.java:141)

I found the problem, as changed isProvider() name and the default value last night and did not update code today.
I will add 2 mock URL separately for Consumer and Provider.

@wu-sheng wu-sheng added this to the 8.10.0 milestone Feb 25, 2022
@wu-sheng wu-sheng merged commit 9efec16 into apache:main Feb 25, 2022
} else {
isConsumer = serviceContext.isConsumerSide();
}
boolean isConsumer = isConsumer(invocation);
Copy link
Copy Markdown
Member

@AlbumenJ AlbumenJ Mar 7, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wu-sheng I'm a little confused about this. Why not judge whether it is the consumer side directly from EnhancedInstance objInst. If objInst is a MonitorFilter object, it should be on the provider side. If objInst is a MonitorClusterFilter object, it should be on the provider side.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We just enhanced MonitorFilter class finally, as MonitorClusterFilter extends MonitorFilter and enhance both of them will cause problem. We have talked above.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@AlbumenJ Agree with @honganan , as a byte code manipulator, once we change the parent class, and the sub classes don't override the changed method, this enhancement actually changes the behavior of all classes on this hierarchy tree.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wu-sheng got it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants