From 1f526682a3b428bf642d17c7bfbff0447a75ee92 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Fri, 12 Apr 2019 10:29:30 +0800 Subject: [PATCH 01/26] Async optimization (#3738) * Result implement CF * Result implement CF * Result implement CF * Add AsyncRpcResult * Fix bugs and refactor Filter * Try to add onSend onError for Filter * invoke different filter method according to result status. * make generic work with async call, including add $invokeAsync * refactor legacy Filter implementation to work with onResponse. * demo changes * Fixes #3620, provider attachment lose on consumer side, fix this by reverting RpcContext copy * AsyncRpcResult should always holds an Invocation instance * refactor filter signature * reimplement embedded Filters * use ProviderModel modification in 3.x * Fix address notification processing workflow after merging 3.x branch * Fix UT * Fix UT * Unit test of JValidator; Clean code of JValidator (#3723) * Fixes #3625 (#3730) use constant to replace magic number * Fix conflict when merging master and 3.x * Fix conflict when merging master and 3.x * Result interface itself has Future status. * Fix DefaultFuture UT * Wrap all protocol Invoker with AsyncToSyncInvoker & Fix UT * Add license * fix UT * Fix ut in MonitorFilterTest * avoid duplicate async to sync wrapper * return async result in CacheFilter. * fix UT in CacheFilterTest * Add generic condition check to GenericFilter callback. * Fix UT * Get generic from RpcContext if the value in Invocation is empty. * Fix RSocketProtocol to meet AbstractProtocol adjustment * rename RpcResult to AppResponse to help avoid confusion with AsyncRpcResult. * RSocket module switch to AsyncRpcResult --- .../support/FailbackClusterInvoker.java | 4 +- .../support/FailsafeClusterInvoker.java | 4 +- .../support/ForkingClusterInvoker.java | 3 +- .../support/MergeableClusterInvoker.java | 32 ++- .../support/wrapper/MockClusterInvoker.java | 4 +- .../apache/dubbo/rpc/cluster/StickyTest.java | 4 +- .../cluster/directory/MockDirInvocation.java | 10 + .../router/file/FileRouterEngineTest.java | 4 +- .../support/FailSafeClusterInvokerTest.java | 4 +- .../support/FailbackClusterInvokerTest.java | 4 +- .../support/FailfastClusterInvokerTest.java | 4 +- .../support/FailoverClusterInvokerTest.java | 4 +- .../support/ForkingClusterInvokerTest.java | 6 +- .../support/MergeableClusterInvokerTest.java | 11 +- .../org/apache/dubbo/common/Constants.java | 7 + .../apache/dubbo/common/logger/Logger.java | 2 +- .../dubbo/common/utils/ReflectUtils.java | 23 ++ .../config/PropertiesConfigurationTest.java | 31 +++ .../com/alibaba/dubbo/rpc/Invocation.java | 9 + .../java/com/alibaba/dubbo/rpc/Result.java | 36 +++- .../apache/dubbo/filter/LegacyInvoker.java | 4 +- .../apache/dubbo/service/MockInvocation.java | 10 + .../consumer/comp/DemoServiceComponent.java | 7 + .../dubbo/demo/provider/DemoServiceImpl.java | 7 + .../dubbo/demo/provider/DemoServiceImpl.java | 7 + .../org/apache/dubbo/demo/DemoService.java | 3 + .../dubbo/demo/consumer/Application.java | 11 +- .../main/resources/spring/dubbo-consumer.xml | 2 +- .../dubbo/demo/provider/DemoServiceImpl.java | 12 ++ .../dubbo/cache/filter/CacheFilter.java | 6 +- .../dubbo/cache/filter/CacheFilterTest.java | 31 +-- .../validation/filter/ValidationFilter.java | 4 +- .../filter/ValidationFilterTest.java | 12 +- .../apache/dubbo/monitor/MonitorService.java | 1 + .../dubbo/monitor/support/MonitorFilter.java | 197 +++++++++-------- .../monitor/support/MonitorFilterTest.java | 16 +- .../dubbo/registry/dubbo/MockChannel.java | 8 +- .../dubbo/registry/dubbo/MockedClient.java | 18 +- .../dubbo/remoting/RemotingException.java | 3 +- .../dubbo/remoting/TimeoutException.java | 3 +- .../remoting/exchange/ExchangeChannel.java | 6 +- .../dubbo/remoting/exchange/Response.java | 61 ++++++ .../remoting/exchange/ResponseFuture.java | 58 ----- .../exchange/support/DefaultFuture.java | 196 ++++------------- .../exchange/support/SimpleFuture.java | 54 ----- .../support/header/HeaderExchangeChannel.java | 6 +- .../support/header/HeaderExchangeClient.java | 6 +- .../support/header/HeaderExchangeHandler.java | 15 +- .../java/org/apache/dubbo/remoting/Main.java | 4 +- .../dubbo/remoting/PerformanceServerTest.java | 1 - .../exchange/support/DefaultFutureTest.java | 4 +- .../handler/HeaderExchangeHandlerTest.java | 2 +- .../transport/mina/ClientToServerTest.java | 5 +- .../support/header/HeartbeatHandlerTest.java | 1 + .../transport/netty/ClientToServerTest.java | 6 +- .../transport/netty4/ClientToServerTest.java | 5 +- .../org/apache/dubbo/rpc/AbstractResult.java | 74 ------- .../org/apache/dubbo/rpc/AppResponse.java | 160 ++++++++++++++ .../org/apache/dubbo/rpc/AsyncRpcResult.java | 201 +++++++++--------- .../java/org/apache/dubbo/rpc/Filter.java | 31 +-- .../org/apache/dubbo/rpc/FutureContext.java | 52 +++++ .../java/org/apache/dubbo/rpc/Invocation.java | 4 + .../java/org/apache/dubbo/rpc/InvokeMode.java | 23 ++ .../apache/dubbo/rpc/ListenableFilter.java | 67 +++--- .../java/org/apache/dubbo/rpc/Result.java | 23 +- .../java/org/apache/dubbo/rpc/RpcContext.java | 35 +-- .../org/apache/dubbo/rpc/RpcInvocation.java | 21 ++ .../java/org/apache/dubbo/rpc/RpcResult.java | 128 ----------- .../dubbo/rpc/SimpleAsyncRpcResult.java | 50 ----- .../dubbo/rpc/filter/ActiveLimitFilter.java | 72 +++++-- .../dubbo/rpc/filter/CompatibleFilter.java | 70 +++--- .../rpc/filter/ConsumerContextFilter.java | 26 ++- .../dubbo/rpc/filter/ContextFilter.java | 24 ++- .../apache/dubbo/rpc/filter/EchoFilter.java | 4 +- .../dubbo/rpc/filter/ExceptionFilter.java | 126 ++++++----- .../dubbo/rpc/filter/ExecuteLimitFilter.java | 34 ++- .../dubbo/rpc/filter/GenericFilter.java | 62 ++++-- .../dubbo/rpc/filter/GenericImplFilter.java | 176 ++++++++------- .../dubbo/rpc/filter/TimeoutFilter.java | 49 ++--- .../dubbo/rpc/protocol/AbstractInvoker.java | 16 +- .../dubbo/rpc/protocol/AbstractProtocol.java | 8 + .../rpc/protocol/AbstractProxyProtocol.java | 7 +- .../rpc/protocol/AsyncToSyncInvoker.java | 89 ++++++++ .../rpc/protocol/ProtocolFilterWrapper.java | 31 ++- .../dubbo/rpc/proxy/AbstractProxyInvoker.java | 46 ++-- .../rpc/proxy/InvokerInvocationHandler.java | 14 +- .../dubbo/rpc/service/GenericService.java | 10 + .../apache/dubbo/rpc/support/MockInvoker.java | 6 +- .../dubbo/rpc/support/MockProtocol.java | 2 +- .../apache/dubbo/rpc/support/RpcUtils.java | 40 ++-- ...pcResultTest.java => AppResponseTest.java} | 0 .../rpc/filter/ActiveLimitFilterTest.java | 24 ++- .../filter/CompatibleFilterFilterTest.java | 39 ++-- .../rpc/filter/ConsumerContextFilterTest.java | 15 +- .../dubbo/rpc/filter/ContextFilterTest.java | 4 +- .../dubbo/rpc/filter/EchoFilterTest.java | 6 +- .../dubbo/rpc/filter/ExceptionFilterTest.java | 37 ++-- .../rpc/filter/ExecuteLimitFilterTest.java | 7 +- .../dubbo/rpc/filter/GenericFilterTest.java | 24 ++- .../rpc/filter/GenericImplFilterTest.java | 21 +- .../dubbo/rpc/filter/TimeoutFilterTest.java | 6 +- .../dubbo/rpc/filter/TokenFilterTest.java | 8 +- .../dubbo/rpc/support/BlockMyInvoker.java | 10 +- .../dubbo/rpc/support/MockInvocation.java | 10 + .../apache/dubbo/rpc/support/MyInvoker.java | 10 +- .../protocol/dubbo/CallbackServiceCodec.java | 3 +- .../protocol/dubbo/ChannelWrappedInvoker.java | 17 +- .../protocol/dubbo/DecodeableRpcResult.java | 4 +- .../rpc/protocol/dubbo/DubboCountCodec.java | 4 +- .../rpc/protocol/dubbo/DubboInvoker.java | 28 +-- .../rpc/protocol/dubbo/DubboProtocol.java | 15 +- .../rpc/protocol/dubbo/FutureAdapter.java | 56 ++--- .../dubbo/LazyConnectExchangeClient.java | 6 +- .../dubbo/ReferenceCountExchangeClient.java | 6 +- .../protocol/dubbo/filter/FutureFilter.java | 56 ++--- .../dubbo/telnet/InvokeTelnetHandler.java | 7 +- .../dubbo/DubboInvokerAvilableTest.java | 20 +- .../rpc/protocol/dubbo/FutureFilterTest.java | 6 +- .../protocol/dubbo/ImplicitCallBackTest.java | 2 +- .../ReferenceCountExchangeClientTest.java | 5 +- .../rpc/protocol/hessian/HessianProtocol.java | 2 +- .../dubbo/rpc/protocol/http/HttpProtocol.java | 4 +- .../rpc/protocol/injvm/InjvmProtocol.java | 2 +- .../protocol/memcached/MemcachedProtocol.java | 10 +- .../rpc/protocol/redis/RedisProtocol.java | 12 +- .../dubbo/rpc/protocol/rest/RestProtocol.java | 2 +- .../dubbo/rpc/protocol/rmi/RmiProtocol.java | 3 +- .../rpc/protocol/thrift/ThriftCodec.java | 10 +- .../rpc/protocol/thrift/ThriftInvoker.java | 11 +- .../rpc/protocol/thrift/ThriftProtocol.java | 9 +- .../rpc/protocol/thrift/ThriftCodecTest.java | 20 +- .../webservice/WebServiceProtocol.java | 2 +- 132 files changed, 1751 insertions(+), 1571 deletions(-) create mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java delete mode 100644 dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseFuture.java delete mode 100644 dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/SimpleFuture.java delete mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/InvokeMode.java rename dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseCallback.java => dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ListenableFilter.java (71%) delete mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcResult.java delete mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/SimpleAsyncRpcResult.java create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AsyncToSyncInvoker.java rename dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/{RpcResultTest.java => AppResponseTest.java} (100%) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvoker.java index dd68d7ef3ddb..e9d090c41335 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvoker.java @@ -24,11 +24,11 @@ import org.apache.dubbo.common.timer.Timer; import org.apache.dubbo.common.timer.TimerTask; import org.apache.dubbo.common.utils.NamedThreadFactory; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; @@ -99,7 +99,7 @@ protected Result doInvoke(Invocation invocation, List> invokers, Load logger.error("Failback to invoke method " + invocation.getMethodName() + ", wait for retry in background. Ignored exception: " + e.getMessage() + ", ", e); addFailed(loadbalance, invocation, invokers, invoker); - return new RpcResult(); // ignore + return AsyncRpcResult.newDefaultAsyncResult(null, null, invocation); // ignore } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java index 0f5378a19a0c..061068a71b0f 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java @@ -18,11 +18,11 @@ import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; @@ -50,7 +50,7 @@ public Result doInvoke(Invocation invocation, List> invokers, LoadBal return invoker.invoke(invocation); } catch (Throwable e) { logger.error("Failsafe ignore exception: " + e.getMessage(), e); - return new RpcResult(); // ignore + return AsyncRpcResult.newDefaultAsyncResult(null, null, invocation); // ignore } } } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java index 184a7b63df64..6b02731304a3 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvoker.java @@ -36,6 +36,8 @@ import java.util.concurrent.atomic.AtomicInteger; /** + * NOTICE! This implementation does not work well with async call. + * * Invoke a specific number of invokers concurrently, usually used for demanding real-time operations, but need to waste more service resources. * * Fork @@ -66,7 +68,6 @@ public Result doInvoke(final Invocation invocation, List> invokers, L } else { selected = new ArrayList<>(); for (int i = 0; i < forks; i++) { - // TODO. Add some comment here, refer chinese version for more details. Invoker invoker = select(loadbalance, invocation, invokers, selected); if (!selected.contains(invoker)) { //Avoid add the same invoker several times. diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java index 82a0e8a2cb7f..400a2c487a6e 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java @@ -23,12 +23,12 @@ import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.NamedThreadFactory; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; import org.apache.dubbo.rpc.cluster.Merger; @@ -41,12 +41,13 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; +/** + * NOTICE! Does not work with async call. + * @param + */ @SuppressWarnings("unchecked") public class MergeableClusterInvoker extends AbstractClusterInvoker { @@ -86,26 +87,19 @@ protected Result doInvoke(Invocation invocation, List> invokers, Load returnType = null; } - Map> results = new HashMap>(); + Map results = new HashMap<>(); for (final Invoker invoker : invokers) { - Future future = executor.submit(new Callable() { - @Override - public Result call() throws Exception { - return invoker.invoke(new RpcInvocation(invocation, invoker)); - } - }); - results.put(invoker.getUrl().getServiceKey(), future); + results.put(invoker.getUrl().getServiceKey(), invoker.invoke(new RpcInvocation(invocation, invoker))); } Object result = null; List resultList = new ArrayList(results.size()); - int timeout = getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT); - for (Map.Entry> entry : results.entrySet()) { - Future future = entry.getValue(); + for (Map.Entry entry : results.entrySet()) { + Result asyncResult = entry.getValue(); try { - Result r = future.get(timeout, TimeUnit.MILLISECONDS); + Result r = asyncResult.get(); if (r.hasException()) { log.error("Invoke " + getGroupDescFromServiceKey(entry.getKey()) + " failed: " + r.getException().getMessage(), @@ -119,13 +113,13 @@ public Result call() throws Exception { } if (resultList.isEmpty()) { - return new RpcResult((Object) null); + return AsyncRpcResult.newDefaultAsyncResult(invocation); } else if (resultList.size() == 1) { return resultList.iterator().next(); } if (returnType == void.class) { - return new RpcResult((Object) null); + return AsyncRpcResult.newDefaultAsyncResult(invocation); } if (merger.startsWith(".")) { @@ -173,7 +167,7 @@ public Result call() throws Exception { throw new RpcException("There is no merger to merge result."); } } - return new RpcResult(result); + return AsyncRpcResult.newDefaultAsyncResult(result, invocation); } diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvoker.java index 59303142d852..1628600a91f3 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/wrapper/MockClusterInvoker.java @@ -22,12 +22,12 @@ import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.CollectionUtils; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.support.MockInvoker; @@ -113,7 +113,7 @@ private Result doMockInvoke(Invocation invocation, RpcException e) { result = minvoker.invoke(invocation); } catch (RpcException me) { if (me.isBiz()) { - result = new RpcResult(me.getCause()); + result = AsyncRpcResult.newDefaultAsyncResult(me.getCause(), invocation); } else { throw new RpcException(me.getCode(), getMockExceptionMessage(e, me), me.getCause()); } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/StickyTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/StickyTest.java index b10fa01c8025..0fce016fbf10 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/StickyTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/StickyTest.java @@ -20,12 +20,12 @@ import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.support.AbstractClusterInvoker; import org.junit.jupiter.api.Assertions; @@ -48,7 +48,7 @@ public class StickyTest { private Invoker invoker2 = mock(Invoker.class); private RpcInvocation invocation; private Directory dic; - private Result result = new RpcResult(); + private Result result = new AppResponse(); private StickyClusterInvoker clusterinvoker = null; private URL url = URL.valueOf("test://test:11/test?" + "&loadbalance=roundrobin" diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java index 279160e71676..07e115d803b9 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/directory/MockDirInvocation.java @@ -51,6 +51,16 @@ public Map getAttachments() { return attachments; } + @Override + public void setAttachment(String key, String value) { + + } + + @Override + public void setAttachmentIfAbsent(String key, String value) { + + } + public Invoker getInvoker() { return null; } diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java index c4cb85daf8bb..74056f38a5b4 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/router/file/FileRouterEngineTest.java @@ -19,12 +19,12 @@ import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.ExtensionLoader; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.LoadBalance; import org.apache.dubbo.rpc.cluster.RouterFactory; @@ -52,7 +52,7 @@ public class FileRouterEngineTest { Invoker invoker2 = mock(Invoker.class); Invocation invocation; StaticDirectory dic; - Result result = new RpcResult(); + Result result = new AppResponse(); private RouterFactory routerFactory = ExtensionLoader.getExtensionLoader(RouterFactory.class).getAdaptiveExtension(); @BeforeAll diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailSafeClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailSafeClusterInvokerTest.java index 413d9b9dc8a5..8ab596bec1e9 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailSafeClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailSafeClusterInvokerTest.java @@ -18,11 +18,11 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.LogUtil; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.filter.DemoService; @@ -48,7 +48,7 @@ public class FailSafeClusterInvokerTest { Invoker invoker = mock(Invoker.class); RpcInvocation invocation = new RpcInvocation(); Directory dic; - Result result = new RpcResult(); + Result result = new AppResponse(); /** * @throws java.lang.Exception diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvokerTest.java index ad96a66830d1..b745b0e1b268 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailbackClusterInvokerTest.java @@ -20,11 +20,11 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.common.utils.DubboAppender; import org.apache.dubbo.common.utils.LogUtil; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.log4j.Level; @@ -59,7 +59,7 @@ public class FailbackClusterInvokerTest { Invoker invoker = mock(Invoker.class); RpcInvocation invocation = new RpcInvocation(); Directory dic; - Result result = new RpcResult(); + Result result = new AppResponse(); /** * @throws java.lang.Exception diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailfastClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailfastClusterInvokerTest.java index 9b6d2e88b73f..6a706868bb9f 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailfastClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailfastClusterInvokerTest.java @@ -17,12 +17,12 @@ package org.apache.dubbo.rpc.cluster.support; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.junit.jupiter.api.Assertions; @@ -47,7 +47,7 @@ public class FailfastClusterInvokerTest { Invoker invoker1 = mock(Invoker.class); RpcInvocation invocation = new RpcInvocation(); Directory dic; - Result result = new RpcResult(); + Result result = new AppResponse(); /** * @throws java.lang.Exception diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java index ff29a6183a96..6a2e76e0474e 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/FailoverClusterInvokerTest.java @@ -17,12 +17,12 @@ package org.apache.dubbo.rpc.cluster.support; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.apache.dubbo.rpc.cluster.directory.StaticDirectory; import org.apache.dubbo.rpc.protocol.AbstractInvoker; @@ -55,7 +55,7 @@ public class FailoverClusterInvokerTest { private Invoker invoker2 = mock(Invoker.class); private RpcInvocation invocation = new RpcInvocation(); private Directory dic; - private Result result = new RpcResult(); + private Result result = new AppResponse(); /** * @throws java.lang.Exception diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvokerTest.java index b3d343a3bbe4..aa27fabe4583 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/ForkingClusterInvokerTest.java @@ -17,12 +17,12 @@ package org.apache.dubbo.rpc.cluster.support; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; -import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.cluster.Directory; import org.junit.jupiter.api.Assertions; @@ -50,7 +50,7 @@ public class ForkingClusterInvokerTest { private Invoker invoker3 = mock(Invoker.class); private RpcInvocation invocation = new RpcInvocation(); private Directory dic; - private Result result = new RpcResult(); + private Result result = new AppResponse(); @BeforeEach public void setUp() throws Exception { diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvokerTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvokerTest.java index 8a4089c9049a..a79a9facc098 100644 --- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvokerTest.java +++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvokerTest.java @@ -18,10 +18,11 @@ import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.AppResponse; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.rpc.cluster.Directory; import org.junit.jupiter.api.Assertions; @@ -119,7 +120,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl return MenuService.class; } if ("invoke".equals(method.getName())) { - return new RpcResult(firstMenu); + return AsyncRpcResult.newDefaultAsyncResult(firstMenu, invocation); } return null; } @@ -135,7 +136,7 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl return MenuService.class; } if ("invoke".equals(method.getName())) { - return new RpcResult(secondMenu); + return AsyncRpcResult.newDefaultAsyncResult(secondMenu, invocation); } return null; } @@ -195,14 +196,14 @@ public void testAddMenu() throws Exception { given(firstInvoker.getUrl()).willReturn( url.addParameter(Constants.GROUP_KEY, "first")); given(firstInvoker.getInterface()).willReturn(MenuService.class); - given(firstInvoker.invoke(invocation)).willReturn(new RpcResult()) + given(firstInvoker.invoke(invocation)).willReturn(new AppResponse()) ; given(firstInvoker.isAvailable()).willReturn(true); given(secondInvoker.getUrl()).willReturn( url.addParameter(Constants.GROUP_KEY, "second")); given(secondInvoker.getInterface()).willReturn(MenuService.class); - given(secondInvoker.invoke(invocation)).willReturn(new RpcResult()) + given(secondInvoker.invoke(invocation)).willReturn(new AppResponse()) ; given(secondInvoker.isAvailable()).willReturn(true); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java index c89a31421fa1..3dc4a7c2aa9d 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/Constants.java @@ -99,6 +99,8 @@ public class Constants { public static final String $INVOKE = "$invoke"; + public static final String $INVOKE_ASYNC = "$invokeAsync"; + public static final String $ECHO = "$echo"; public static final int DEFAULT_IO_THREADS = Math.min(Runtime.getRuntime().availableProcessors() + 1, 32); @@ -847,6 +849,11 @@ public class Constants { */ public static final String DEVELOPMENT_ENVIRONMENT = "develop"; + /** + * Consumer side 's proxy class + */ + public static final String PROXY_CLASS_REF = "refClass"; + /** * Production environment key. */ diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/Logger.java b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/Logger.java index c505326d0c3b..874ab564a2ee 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/logger/Logger.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/logger/Logger.java @@ -142,7 +142,7 @@ public interface Logger { /** * Is debug logging currently enabled? - * + *  * @return true if debug is enabled */ boolean isDebugEnabled(); diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java index ccec6875ca83..0c1a13dfe25d 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ReflectUtils.java @@ -28,6 +28,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; import java.net.URL; import java.security.CodeSource; import java.security.ProtectionDomain; @@ -39,6 +40,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.Future; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -1096,4 +1098,25 @@ public static Map getBeanPropertyReadMethods(Class cl) { return properties; } + + public static Type[] getReturnTypes(Method method) { + Class returnType = method.getReturnType(); + Type genericReturnType = method.getGenericReturnType(); + if (Future.class.isAssignableFrom(returnType)) { + if (genericReturnType instanceof ParameterizedType) { + Type actualArgType = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0]; + if (actualArgType instanceof ParameterizedType) { + returnType = (Class) ((ParameterizedType) actualArgType).getRawType(); + genericReturnType = actualArgType; + } else { + returnType = (Class) actualArgType; + genericReturnType = returnType; + } + } else { + returnType = null; + genericReturnType = null; + } + } + return new Type[]{returnType, genericReturnType}; + } } \ No newline at end of file diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java new file mode 100644 index 000000000000..30b81f0a67f8 --- /dev/null +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java @@ -0,0 +1,31 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.common.config; + + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class PropertiesConfigurationTest { + + @Test + public void testOrderPropertiesProviders() { + PropertiesConfiguration configuration = new PropertiesConfiguration("test", null); + Assertions.assertTrue(configuration.getInternalProperty("testKey").equals("999")); + } + +} diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java index b96d14d1ee4a..591af2c62037 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Invocation.java @@ -29,6 +29,15 @@ default org.apache.dubbo.rpc.Invocation getOriginal() { return null; } + @Override + default void setAttachmentIfAbsent(String key, String value) { + } + + @Override + default void setAttachment(String key, String value) { + + } + class CompatibleInvocation implements Invocation { private org.apache.dubbo.rpc.Invocation delegate; diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java index a661b2b6b5b0..22531301be17 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java @@ -17,11 +17,42 @@ package com.alibaba.dubbo.rpc; +import org.apache.dubbo.rpc.AppResponse; + import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; @Deprecated public interface Result extends org.apache.dubbo.rpc.Result { + @Override + default void setValue(Object value) { + + } + + @Override + default void setException(Throwable t) { + + } + + @Override + default org.apache.dubbo.rpc.Result thenApplyWithContext(Function fn) { + return this; + } + + @Override + default CompletableFuture thenApply(Function fn) { + return null; + } + + @Override + default org.apache.dubbo.rpc.Result get() throws InterruptedException, ExecutionException { + return this; + } + + class CompatibleResult implements Result { private org.apache.dubbo.rpc.Result delegate; @@ -53,11 +84,6 @@ public Object recreate() throws Throwable { return delegate.recreate(); } - @Override - public Object getResult() { - return delegate.getResult(); - } - @Override public Map getAttachments() { return delegate.getAttachments(); diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java index ee1288affffd..f77e0a523d08 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/filter/LegacyInvoker.java @@ -17,7 +17,7 @@ package org.apache.dubbo.filter; -import org.apache.dubbo.rpc.RpcResult; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.service.DemoService; import com.alibaba.dubbo.common.URL; @@ -58,7 +58,7 @@ public boolean isAvailable() { } public Result invoke(Invocation invocation) throws RpcException { - RpcResult result = new RpcResult(); + AppResponse result = new AppResponse(); if (hasException == false) { result.setValue("alibaba"); } else { diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java b/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java index 148b5bce5f5f..73706a087ba7 100644 --- a/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java +++ b/dubbo-compatible/src/test/java/org/apache/dubbo/service/MockInvocation.java @@ -57,6 +57,16 @@ public Map getAttachments() { return attachments; } + @Override + public void setAttachment(String key, String value) { + + } + + @Override + public void setAttachmentIfAbsent(String key, String value) { + + } + public Invoker getInvoker() { return null; } diff --git a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java index 4305ed6c05f6..db6b7559a769 100644 --- a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java +++ b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java @@ -24,6 +24,8 @@ import org.springframework.stereotype.Component; +import java.util.concurrent.CompletableFuture; + @Component("demoServiceComponent") public class DemoServiceComponent implements DemoService { @Reference @@ -33,4 +35,9 @@ public class DemoServiceComponent implements DemoService { public String sayHello(String name) { return demoService.sayHello(name); } + + @Override + public CompletableFuture sayHelloAsync(String name) { + return null; + } } diff --git a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java index cb06537ae012..137fa23ead6a 100644 --- a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java @@ -25,6 +25,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.CompletableFuture; + @Service public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @@ -35,4 +37,9 @@ public String sayHello(String name) { return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } + @Override + public CompletableFuture sayHelloAsync(String name) { + return null; + } + } diff --git a/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java b/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java index 5e2ef2350d25..2f13a5c6714e 100644 --- a/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java @@ -22,6 +22,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.CompletableFuture; + public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @@ -31,4 +33,9 @@ public String sayHello(String name) { return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } + @Override + public CompletableFuture sayHelloAsync(String name) { + return null; + } + } diff --git a/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java b/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java index 1172c9be0fc3..bd9c9287de75 100644 --- a/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java +++ b/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java @@ -16,8 +16,11 @@ */ package org.apache.dubbo.demo; +import java.util.concurrent.CompletableFuture; + public interface DemoService { String sayHello(String name); + CompletableFuture sayHelloAsync(String name); } \ No newline at end of file diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java index 90ed7c0b6a6b..ad34442a4364 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java @@ -20,16 +20,21 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; +import java.util.concurrent.CompletableFuture; + public class Application { /** * In order to make sure multicast registry works, need to specify '-Djava.net.preferIPv4Stack=true' before * launch the application */ - public static void main(String[] args) { + public static void main(String[] args) throws Exception { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml"); context.start(); DemoService demoService = context.getBean("demoService", DemoService.class); - String hello = demoService.sayHello("world"); - System.out.println("result: " + hello); +// String hello = demoService.sayHello("world"); + CompletableFuture helloFuture = demoService.sayHelloAsync("world"); +// System.out.println("result: " + hello); + System.out.println("result: " + helloFuture.get()); + System.in.read(); } } diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml index 6b5efc32f00b..286b24b3f15e 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml @@ -27,6 +27,6 @@ - + diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java index d0d315c9b4e6..e95caa60444a 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java @@ -22,6 +22,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.concurrent.CompletableFuture; + public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @@ -31,4 +33,14 @@ public String sayHello(String name) { return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } + @Override + public CompletableFuture sayHelloAsync(String name) { + try { + Thread.sleep(10000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return CompletableFuture.completedFuture("future return value!"); + } + } diff --git a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java index 4de9f5a170c3..2f207b83b08c 100644 --- a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java +++ b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java @@ -22,12 +22,12 @@ import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.RpcResult; import java.io.Serializable; @@ -95,9 +95,9 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept Object value = cache.get(key); if (value != null) { if (value instanceof ValueWrapper) { - return new RpcResult(((ValueWrapper)value).get()); + return AsyncRpcResult.newDefaultAsyncResult(((ValueWrapper) value).get(), invocation); } else { - return new RpcResult(value); + return AsyncRpcResult.newDefaultAsyncResult(value, invocation); } } Result result = invoker.invoke(invocation); diff --git a/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java b/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java index c64647309f0d..217919f1d6fa 100644 --- a/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java +++ b/dubbo-filter/dubbo-filter-cache/src/test/java/org/apache/dubbo/cache/filter/CacheFilterTest.java @@ -22,9 +22,10 @@ import org.apache.dubbo.cache.support.lru.LruCacheFactory; import org.apache.dubbo.cache.support.threadlocal.ThreadLocalCacheFactory; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.params.ParameterizedTest; @@ -60,19 +61,19 @@ public void setUp(String cacheType, CacheFactory cacheFactory) { URL url = URL.valueOf("test://test:11/test?cache=" + cacheType); - given(invoker.invoke(invocation)).willReturn(new RpcResult("value")); + given(invoker.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value", invocation)); given(invoker.getUrl()).willReturn(url); - given(invoker1.invoke(invocation)).willReturn(new RpcResult("value1")); + given(invoker1.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value1", invocation)); given(invoker1.getUrl()).willReturn(url); - given(invoker2.invoke(invocation)).willReturn(new RpcResult("value2")); + given(invoker2.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult("value2", invocation)); given(invoker2.getUrl()).willReturn(url); - given(invoker3.invoke(invocation)).willReturn(new RpcResult(new RuntimeException())); + given(invoker3.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(new RuntimeException(), invocation)); given(invoker3.getUrl()).willReturn(url); - given(invoker4.invoke(invocation)).willReturn(new RpcResult()); + given(invoker4.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(invocation)); given(invoker4.getUrl()).willReturn(url); } @@ -85,8 +86,8 @@ public void testNonArgsMethod(String cacheType, CacheFactory cacheFactory) { invocation.setArguments(new Object[]{}); cacheFilter.invoke(invoker, invocation); - RpcResult rpcResult1 = (RpcResult) cacheFilter.invoke(invoker1, invocation); - RpcResult rpcResult2 = (RpcResult) cacheFilter.invoke(invoker2, invocation); + Result rpcResult1 = cacheFilter.invoke(invoker1, invocation); + Result rpcResult2 = cacheFilter.invoke(invoker2, invocation); Assertions.assertEquals(rpcResult1.getValue(), rpcResult2.getValue()); Assertions.assertEquals(rpcResult1.getValue(), "value"); } @@ -100,8 +101,8 @@ public void testMethodWithArgs(String cacheType, CacheFactory cacheFactory) { invocation.setArguments(new Object[]{"arg1"}); cacheFilter.invoke(invoker, invocation); - RpcResult rpcResult1 = (RpcResult) cacheFilter.invoke(invoker1, invocation); - RpcResult rpcResult2 = (RpcResult) cacheFilter.invoke(invoker2, invocation); + Result rpcResult1 = cacheFilter.invoke(invoker1, invocation); + Result rpcResult2 = cacheFilter.invoke(invoker2, invocation); Assertions.assertEquals(rpcResult1.getValue(), rpcResult2.getValue()); Assertions.assertEquals(rpcResult1.getValue(), "value"); } @@ -115,7 +116,7 @@ public void testException(String cacheType, CacheFactory cacheFactory) { invocation.setArguments(new Object[]{"arg2"}); cacheFilter.invoke(invoker3, invocation); - RpcResult rpcResult = (RpcResult) cacheFilter.invoke(invoker2, invocation); + Result rpcResult = cacheFilter.invoke(invoker2, invocation); Assertions.assertEquals(rpcResult.getValue(), "value2"); } @@ -128,9 +129,9 @@ public void testNull(String cacheType, CacheFactory cacheFactory) { invocation.setArguments(new Object[]{"arg3"}); cacheFilter.invoke(invoker4, invocation); - RpcResult rpcResult1 = (RpcResult) cacheFilter.invoke(invoker1, invocation); - RpcResult rpcResult2 = (RpcResult) cacheFilter.invoke(invoker2, invocation); - Assertions.assertEquals(rpcResult1.getValue(), null); - Assertions.assertEquals(rpcResult2.getValue(), null); + Result result1 = cacheFilter.invoke(invoker1, invocation); + Result result2 = cacheFilter.invoke(invoker2, invocation); + Assertions.assertEquals(result1.getValue(), null); + Assertions.assertEquals(result2.getValue(), null); } } diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java index 2af761a09583..84950c395e11 100644 --- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java +++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/filter/ValidationFilter.java @@ -19,12 +19,12 @@ import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.ConfigUtils; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.validation.Validation; import org.apache.dubbo.validation.Validator; @@ -87,7 +87,7 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept } catch (RpcException e) { throw e; } catch (Throwable t) { - return new RpcResult(t); + return AsyncRpcResult.newDefaultAsyncResult(t, invocation); } } return invoker.invoke(invocation); diff --git a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java index cade59364022..b757536e9da7 100644 --- a/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java +++ b/dubbo-filter/dubbo-filter-validation/src/test/java/org/apache/dubbo/validation/filter/ValidationFilterTest.java @@ -17,11 +17,11 @@ package org.apache.dubbo.validation.filter; import org.apache.dubbo.common.URL; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; -import org.apache.dubbo.rpc.RpcResult; import org.apache.dubbo.validation.Validation; import org.apache.dubbo.validation.Validator; @@ -52,7 +52,7 @@ public void testItWithNotExistClass() throws Exception { URL url = URL.valueOf("test://test:11/test?default.validation=true"); given(validation.getValidator(url)).willThrow(new IllegalStateException("Not found class test, cause: test")); - given(invoker.invoke(invocation)).willReturn(new RpcResult("success")); + given(invoker.invoke(invocation)).willReturn(new AppResponse("success")); given(invoker.getUrl()).willReturn(url); given(invocation.getMethodName()).willReturn("echo1"); given(invocation.getParameterTypes()).willReturn(new Class[]{String.class}); @@ -70,7 +70,7 @@ public void testItWithExistClass() throws Exception { URL url = URL.valueOf("test://test:11/test?default.validation=true"); given(validation.getValidator(url)).willReturn(validator); - given(invoker.invoke(invocation)).willReturn(new RpcResult("success")); + given(invoker.invoke(invocation)).willReturn(new AppResponse("success")); given(invoker.getUrl()).willReturn(url); given(invocation.getMethodName()).willReturn("echo1"); given(invocation.getParameterTypes()).willReturn(new Class[]{String.class}); @@ -87,7 +87,7 @@ public void testItWithoutUrlParameters() throws Exception { URL url = URL.valueOf("test://test:11/test"); given(validation.getValidator(url)).willReturn(validator); - given(invoker.invoke(invocation)).willReturn(new RpcResult("success")); + given(invoker.invoke(invocation)).willReturn(new AppResponse("success")); given(invoker.getUrl()).willReturn(url); given(invocation.getMethodName()).willReturn("echo1"); given(invocation.getParameterTypes()).willReturn(new Class[]{String.class}); @@ -104,7 +104,7 @@ public void testItWhileMethodNameStartWithDollar() throws Exception { URL url = URL.valueOf("test://test:11/test"); given(validation.getValidator(url)).willReturn(validator); - given(invoker.invoke(invocation)).willReturn(new RpcResult("success")); + given(invoker.invoke(invocation)).willReturn(new AppResponse("success")); given(invoker.getUrl()).willReturn(url); given(invocation.getMethodName()).willReturn("$echo1"); given(invocation.getParameterTypes()).willReturn(new Class[]{String.class}); @@ -124,7 +124,7 @@ public void testItWhileThrowoutRpcException() throws Exception { URL url = URL.valueOf("test://test:11/test?default.validation=true"); given(validation.getValidator(url)).willThrow(new RpcException("rpc exception")); - given(invoker.invoke(invocation)).willReturn(new RpcResult("success")); + given(invoker.invoke(invocation)).willReturn(new AppResponse("success")); given(invoker.getUrl()).willReturn(url); given(invocation.getMethodName()).willReturn("echo1"); given(invocation.getParameterTypes()).willReturn(new Class[]{String.class}); diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorService.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorService.java index e6b905012645..06280ceaf25b 100644 --- a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorService.java +++ b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/MonitorService.java @@ -86,4 +86,5 @@ public interface MonitorService { */ List lookup(URL query); + } \ No newline at end of file diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java index 10eb31e42fcc..5358719e75ec 100644 --- a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java +++ b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java @@ -25,9 +25,9 @@ import org.apache.dubbo.monitor.Monitor; import org.apache.dubbo.monitor.MonitorFactory; import org.apache.dubbo.monitor.MonitorService; -import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.ListenableFilter; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; @@ -41,10 +41,14 @@ * MonitorFilter. (SPI, Singleton, ThreadSafe) */ @Activate(group = {Constants.PROVIDER, Constants.CONSUMER}) -public class MonitorFilter implements Filter { +public class MonitorFilter extends ListenableFilter { private static final Logger logger = LoggerFactory.getLogger(MonitorFilter.class); + private static final String MONITOR_FILTER_START_TIME = "monitor_filter_start_time"; + public MonitorFilter() { + super.listener = new MonitorListener(); + } /** * The Concurrent counter */ @@ -59,6 +63,7 @@ public void setMonitorFactory(MonitorFactory monitorFactory) { this.monitorFactory = monitorFactory; } + /** * The invocation interceptor,it will collect the invoke data about this invocation and send it to monitor center * @@ -70,105 +75,10 @@ public void setMonitorFactory(MonitorFactory monitorFactory) { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) { - RpcContext context = RpcContext.getContext(); // provider must fetch context before invoke() gets called - String remoteHost = context.getRemoteHost(); - long start = System.currentTimeMillis(); // record start timestamp + invocation.setAttachment(MONITOR_FILTER_START_TIME, String.valueOf(System.currentTimeMillis())); getConcurrent(invoker, invocation).incrementAndGet(); // count up - try { - Result result = invoker.invoke(invocation); // proceed invocation chain - collect(invoker, invocation, result, remoteHost, start, false); - return result; - } catch (RpcException e) { - collect(invoker, invocation, null, remoteHost, start, true); - throw e; - } finally { - getConcurrent(invoker, invocation).decrementAndGet(); // count down - } - } else { - return invoker.invoke(invocation); - } - } - - /** - * The collector logic, it will be handled by the default monitor - * - * @param invoker - * @param invocation - * @param result the invoke result - * @param remoteHost the remote host address - * @param start the timestamp the invoke begin - * @param error if there is an error on the invoke - */ - private void collect(Invoker invoker, Invocation invocation, Result result, String remoteHost, long start, boolean error) { - try { - URL monitorUrl = invoker.getUrl().getUrlParameter(Constants.MONITOR_KEY); - Monitor monitor = monitorFactory.getMonitor(monitorUrl); - if (monitor == null) { - return; - } - URL statisticsURL = createStatisticsUrl(invoker, invocation, result, remoteHost, start, error); - monitor.collect(statisticsURL); - } catch (Throwable t) { - logger.warn("Failed to monitor count service " + invoker.getUrl() + ", cause: " + t.getMessage(), t); } - } - - /** - * Create statistics url - * - * @param invoker - * @param invocation - * @param result - * @param remoteHost - * @param start - * @param error - * @return - */ - private URL createStatisticsUrl(Invoker invoker, Invocation invocation, Result result, String remoteHost, long start, boolean error) { - // ---- service statistics ---- - long elapsed = System.currentTimeMillis() - start; // invocation cost - int concurrent = getConcurrent(invoker, invocation).get(); // current concurrent count - String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY); - String service = invoker.getInterface().getName(); // service name - String method = RpcUtils.getMethodName(invocation); // method name - String group = invoker.getUrl().getParameter(Constants.GROUP_KEY); - String version = invoker.getUrl().getParameter(Constants.VERSION_KEY); - - int localPort; - String remoteKey, remoteValue; - if (Constants.CONSUMER_SIDE.equals(invoker.getUrl().getParameter(Constants.SIDE_KEY))) { - // ---- for service consumer ---- - localPort = 0; - remoteKey = MonitorService.PROVIDER; - remoteValue = invoker.getUrl().getAddress(); - } else { - // ---- for service provider ---- - localPort = invoker.getUrl().getPort(); - remoteKey = MonitorService.CONSUMER; - remoteValue = remoteHost; - } - String input = "", output = ""; - if (invocation.getAttachment(Constants.INPUT_KEY) != null) { - input = invocation.getAttachment(Constants.INPUT_KEY); - } - if (result != null && result.getAttachment(Constants.OUTPUT_KEY) != null) { - output = result.getAttachment(Constants.OUTPUT_KEY); - } - - return new URL(Constants.COUNT_PROTOCOL, - NetUtils.getLocalHost(), localPort, - service + Constants.PATH_SEPARATOR + method, - MonitorService.APPLICATION, application, - MonitorService.INTERFACE, service, - MonitorService.METHOD, method, - remoteKey, remoteValue, - error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1", - MonitorService.ELAPSED, String.valueOf(elapsed), - MonitorService.CONCURRENT, String.valueOf(concurrent), - Constants.INPUT_KEY, input, - Constants.OUTPUT_KEY, output, - Constants.GROUP_KEY, group, - Constants.VERSION_KEY, version); + return invoker.invoke(invocation); // proceed invocation chain } // concurrent counter @@ -182,4 +92,93 @@ private AtomicInteger getConcurrent(Invoker invoker, Invocation invocation) { return concurrent; } + class MonitorListener implements Listener { + + @Override + public void onResponse(Result result, Invoker invoker, Invocation invocation) { + if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) { + collect(invoker, invocation, result, RpcContext.getContext().getRemoteHost(), Long.valueOf(invocation.getAttachment(MONITOR_FILTER_START_TIME)), false); + getConcurrent(invoker, invocation).decrementAndGet(); // count down + } + } + + @Override + public void onError(Throwable t, Invoker invoker, Invocation invocation) { + if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) { + collect(invoker, invocation, null, RpcContext.getContext().getRemoteHost(), Long.valueOf(invocation.getAttachment(MONITOR_FILTER_START_TIME)), true); + getConcurrent(invoker, invocation).decrementAndGet(); // count down + } + } + + /** + * The collector logic, it will be handled by the default monitor + * + * @param invoker + * @param invocation + * @param result the invoke result + * @param remoteHost the remote host address + * @param start the timestamp the invoke begin + * @param error if there is an error on the invoke + */ + private void collect(Invoker invoker, Invocation invocation, Result result, String remoteHost, long start, boolean error) { + try { + URL monitorUrl = invoker.getUrl().getUrlParameter(Constants.MONITOR_KEY); + Monitor monitor = monitorFactory.getMonitor(monitorUrl); + if (monitor == null) { + return; + } + URL statisticsURL = createStatisticsUrl(invoker, invocation, result, remoteHost, start, error); + monitor.collect(statisticsURL); + } catch (Throwable t) { + logger.warn("Failed to monitor count service " + invoker.getUrl() + ", cause: " + t.getMessage(), t); + } + } + + /** + * Create statistics url + * + * @param invoker + * @param invocation + * @param result + * @param remoteHost + * @param start + * @param error + * @return + */ + private URL createStatisticsUrl(Invoker invoker, Invocation invocation, Result result, String remoteHost, long start, boolean error) { + // ---- service statistics ---- + long elapsed = System.currentTimeMillis() - start; // invocation cost + int concurrent = getConcurrent(invoker, invocation).get(); // current concurrent count + String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY); + String service = invoker.getInterface().getName(); // service name + String method = RpcUtils.getMethodName(invocation); // method name + String group = invoker.getUrl().getParameter(Constants.GROUP_KEY); + String version = invoker.getUrl().getParameter(Constants.VERSION_KEY); + + int localPort; + String remoteKey, remoteValue; + if (Constants.CONSUMER_SIDE.equals(invoker.getUrl().getParameter(Constants.SIDE_KEY))) { + // ---- for service consumer ---- + localPort = 0; + remoteKey = MonitorService.PROVIDER; + remoteValue = invoker.getUrl().getAddress(); + } else { + // ---- for service provider ---- + localPort = invoker.getUrl().getPort(); + remoteKey = MonitorService.CONSUMER; + remoteValue = remoteHost; + } + String input = "", output = ""; + if (invocation.getAttachment(Constants.INPUT_KEY) != null) { + input = invocation.getAttachment(Constants.INPUT_KEY); + } + if (result != null && result.getAttachment(Constants.OUTPUT_KEY) != null) { + output = result.getAttachment(Constants.OUTPUT_KEY); + } + + return new URL(Constants.COUNT_PROTOCOL, NetUtils.getLocalHost(), localPort, service + Constants.PATH_SEPARATOR + method, MonitorService.APPLICATION, application, MonitorService.INTERFACE, service, MonitorService.METHOD, method, remoteKey, remoteValue, error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1", MonitorService.ELAPSED, String.valueOf(elapsed), MonitorService.CONCURRENT, String.valueOf(concurrent), Constants.INPUT_KEY, input, Constants.OUTPUT_KEY, output, Constants.GROUP_KEY, group, Constants.VERSION_KEY, version); + } + + } + } diff --git a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MonitorFilterTest.java b/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MonitorFilterTest.java index 01ba57dd7b85..730ab28e483b 100644 --- a/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MonitorFilterTest.java +++ b/dubbo-monitor/dubbo-monitor-api/src/test/java/org/apache/dubbo/monitor/support/MonitorFilterTest.java @@ -22,12 +22,14 @@ import org.apache.dubbo.monitor.Monitor; import org.apache.dubbo.monitor.MonitorFactory; import org.apache.dubbo.monitor.MonitorService; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcInvocation; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -73,7 +75,7 @@ public boolean isAvailable() { public Result invoke(Invocation invocation) throws RpcException { lastInvocation = invocation; - return null; + return AsyncRpcResult.newDefaultAsyncResult(invocation); } @Override @@ -115,7 +117,11 @@ public void testFilter() throws Exception { monitorFilter.setMonitorFactory(monitorFactory); Invocation invocation = new RpcInvocation("aaa", new Class[0], new Object[0]); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); - monitorFilter.invoke(serviceInvoker, invocation); + Result result = monitorFilter.invoke(serviceInvoker, invocation); + result.thenApplyWithContext((r) -> { + monitorFilter.listener().onResponse(r, serviceInvoker, invocation); + return r; + }); while (lastStatistics == null) { Thread.sleep(10); } @@ -151,7 +157,11 @@ public void testGenericFilter() throws Exception { monitorFilter.setMonitorFactory(monitorFactory); Invocation invocation = new RpcInvocation("$invoke", new Class[]{String.class, String[].class, Object[].class}, new Object[]{"xxx", new String[]{}, new Object[]{}}); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); - monitorFilter.invoke(serviceInvoker, invocation); + Result result = monitorFilter.invoke(serviceInvoker, invocation); + result.thenApplyWithContext((r) -> { + monitorFilter.listener().onResponse(r, serviceInvoker, invocation); + return r; + }); while (lastStatistics == null) { Thread.sleep(10); } diff --git a/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java b/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java index fa061b996968..7a4961bf9548 100644 --- a/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java +++ b/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockChannel.java @@ -21,9 +21,9 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.ExchangeHandler; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import java.net.InetSocketAddress; +import java.util.concurrent.CompletableFuture; public class MockChannel implements ExchangeChannel { @@ -76,7 +76,7 @@ public URL getUrl() { return null; } - public ResponseFuture send(Object request, int timeout) throws RemotingException { + public CompletableFuture send(Object request, int timeout) throws RemotingException { return null; } @@ -85,11 +85,11 @@ public ChannelHandler getChannelHandler() { return null; } - public ResponseFuture request(Object request) throws RemotingException { + public CompletableFuture request(Object request) throws RemotingException { return null; } - public ResponseFuture request(Object request, int timeout) throws RemotingException { + public CompletableFuture request(Object request, int timeout) throws RemotingException { return null; } diff --git a/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java b/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java index f1341ef71f86..1afe0d550c8e 100644 --- a/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java +++ b/dubbo-registry/dubbo-registry-default/src/test/java/org/apache/dubbo/registry/dubbo/MockedClient.java @@ -23,12 +23,13 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.exchange.ExchangeClient; import org.apache.dubbo.remoting.exchange.ExchangeHandler; -import org.apache.dubbo.remoting.exchange.ResponseCallback; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import org.apache.dubbo.remoting.exchange.support.Replier; import java.net.InetSocketAddress; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; /** * MockedClient @@ -79,27 +80,24 @@ public void send(Object msg) throws RemotingException { this.sent = msg; } - public ResponseFuture request(Object msg) throws RemotingException { + public CompletableFuture request(Object msg) throws RemotingException { return request(msg, 0); } - public ResponseFuture request(Object msg, int timeout) throws RemotingException { + public CompletableFuture request(Object msg, int timeout) throws RemotingException { this.invoked = msg; - return new ResponseFuture() { - public Object get() throws RemotingException { + return new CompletableFuture() { + public Object get() throws InterruptedException, ExecutionException { return received; } - public Object get(int timeoutInMillis) throws RemotingException { + public Object get(int timeoutInMillis) throws InterruptedException, ExecutionException, TimeoutException { return received; } public boolean isDone() { return true; } - - public void setCallback(ResponseCallback callback) { - } }; } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingException.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingException.java index fb288bb96433..1bbd4c254734 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingException.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/RemotingException.java @@ -22,8 +22,7 @@ * RemotingException. (API, Prototype, ThreadSafe) * * @export - * @see org.apache.dubbo.remoting.exchange.ResponseFuture#get() - * @see org.apache.dubbo.remoting.exchange.ResponseFuture#get(int) + * @see org.apache.dubbo.remoting.exchange.support.DefaultFuture#get() * @see org.apache.dubbo.remoting.Channel#send(Object, boolean) * @see org.apache.dubbo.remoting.exchange.ExchangeChannel#request(Object) * @see org.apache.dubbo.remoting.exchange.ExchangeChannel#request(Object, int) diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/TimeoutException.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/TimeoutException.java index 464452e1afe4..a14371645fa0 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/TimeoutException.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/TimeoutException.java @@ -22,8 +22,7 @@ * TimeoutException. (API, Prototype, ThreadSafe) * * @export - * @see org.apache.dubbo.remoting.exchange.ResponseFuture#get() - * @see org.apache.dubbo.remoting.exchange.ResponseFuture#get(int) + * @see org.apache.dubbo.remoting.exchange.support.DefaultFuture#get() */ public class TimeoutException extends RemotingException { diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeChannel.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeChannel.java index 3922626fdfb1..0e4917d200f0 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeChannel.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ExchangeChannel.java @@ -19,6 +19,8 @@ import org.apache.dubbo.remoting.Channel; import org.apache.dubbo.remoting.RemotingException; +import java.util.concurrent.CompletableFuture; + /** * ExchangeChannel. (API/SPI, Prototype, ThreadSafe) */ @@ -31,7 +33,7 @@ public interface ExchangeChannel extends Channel { * @return response future * @throws RemotingException */ - ResponseFuture request(Object request) throws RemotingException; + CompletableFuture request(Object request) throws RemotingException; /** * send request. @@ -41,7 +43,7 @@ public interface ExchangeChannel extends Channel { * @return response future * @throws RemotingException */ - ResponseFuture request(Object request, int timeout) throws RemotingException; + CompletableFuture request(Object request, int timeout) throws RemotingException; /** * get message handler. diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java index 568ecf1160b2..b0453d61352c 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java @@ -16,6 +16,16 @@ */ package org.apache.dubbo.remoting.exchange; +import org.apache.dubbo.remoting.Channel; +import org.apache.dubbo.remoting.Codec; +import org.apache.dubbo.remoting.Decodeable; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.HashMap; +import java.util.Map; + /** * Response */ @@ -173,4 +183,55 @@ public String toString() { return "Response [id=" + mId + ", version=" + mVersion + ", status=" + mStatus + ", event=" + mEvent + ", error=" + mErrorMsg + ", result=" + (mResult == this ? "this" : mResult) + "]"; } + + public static class AppResult { + + protected Map attachments = new HashMap(); + + protected Object result; + + protected Throwable exception; + + public Map getAttachments() { + return attachments; + } + + public void setAttachments(Map attachments) { + this.attachments = attachments; + } + + public Object getResult() { + return result; + } + + public void setResult(Object result) { + this.result = result; + } + + public Throwable getException() { + return exception; + } + + public void setException(Throwable exception) { + this.exception = exception; + } + } + + public static class DecodeableAppResult implements Codec, Decodeable { + + @Override + public void decode() throws Exception { + + } + + @Override + public void encode(Channel channel, OutputStream output, Object message) throws IOException { + + } + + @Override + public Object decode(Channel channel, InputStream input) throws IOException { + return null; + } + } } \ No newline at end of file diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseFuture.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseFuture.java deleted file mode 100644 index 9e641dd3579d..000000000000 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseFuture.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.remoting.exchange; - -import org.apache.dubbo.remoting.RemotingException; - -/** - * Future. (API/SPI, Prototype, ThreadSafe) - * - * @see org.apache.dubbo.remoting.exchange.ExchangeChannel#request(Object) - * @see org.apache.dubbo.remoting.exchange.ExchangeChannel#request(Object, int) - */ -public interface ResponseFuture { - - /** - * get result. - * - * @return result. - */ - Object get() throws RemotingException; - - /** - * get result with the specified timeout. - * - * @param timeoutInMillis timeout. - * @return result. - */ - Object get(int timeoutInMillis) throws RemotingException; - - /** - * set callback. - * - * @param callback - */ - void setCallback(ResponseCallback callback); - - /** - * check is done. - * - * @return done or not. - */ - boolean isDone(); - -} \ No newline at end of file diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java index 290d668241a9..3324ad994ac6 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java @@ -29,22 +29,18 @@ import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Response; -import org.apache.dubbo.remoting.exchange.ResponseCallback; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Map; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; /** * DefaultFuture. */ -public class DefaultFuture implements ResponseFuture { +public class DefaultFuture extends CompletableFuture { private static final Logger logger = LoggerFactory.getLogger(DefaultFuture.class); @@ -62,12 +58,8 @@ public class DefaultFuture implements ResponseFuture { private final Channel channel; private final Request request; private final int timeout; - private final Lock lock = new ReentrantLock(); - private final Condition done = lock.newCondition(); private final long start = System.currentTimeMillis(); private volatile long sent; - private volatile Response response; - private volatile ResponseCallback callback; private DefaultFuture(Channel channel, Request request, int timeout) { this.channel = channel; @@ -79,14 +71,6 @@ private DefaultFuture(Channel channel, Request request, int timeout) { CHANNELS.put(id, channel); } - /** - * check time out of the future - */ - private static void timeoutCheck(DefaultFuture future) { - TimeoutCheckTask task = new TimeoutCheckTask(future); - TIME_OUT_TIMER.newTimeout(task, future.getTimeout(), TimeUnit.MILLISECONDS); - } - /** * init a DefaultFuture * 1.init a DefaultFuture @@ -160,141 +144,32 @@ public static void received(Channel channel, Response response) { } @Override - public Object get() throws RemotingException { - return get(timeout); - } - - @Override - public Object get(int timeout) throws RemotingException { - if (timeout <= 0) { - timeout = Constants.DEFAULT_TIMEOUT; - } - if (!isDone()) { - long start = System.currentTimeMillis(); - lock.lock(); - try { - while (!isDone()) { - done.await(timeout, TimeUnit.MILLISECONDS); - if (isDone() || System.currentTimeMillis() - start > timeout) { - break; - } - } - } catch (InterruptedException e) { - throw new RuntimeException(e); - } finally { - lock.unlock(); - } - if (!isDone()) { - throw new TimeoutException(sent > 0, channel, getTimeoutMessage(false)); - } - } - return returnFromResponse(); - } - - public void cancel() { + public boolean cancel(boolean mayInterruptIfRunning) { Response errorResult = new Response(id); + errorResult.setStatus(Response.CLIENT_ERROR); errorResult.setErrorMessage("request future has been canceled."); - response = errorResult; + this.doReceived(errorResult); FUTURES.remove(id); CHANNELS.remove(id); + return true; } - @Override - public boolean isDone() { - return response != null; - } - - @Override - public void setCallback(ResponseCallback callback) { - if (isDone()) { - invokeCallback(callback); - } else { - boolean isdone = false; - lock.lock(); - try { - if (!isDone()) { - this.callback = callback; - } else { - isdone = true; - } - } finally { - lock.unlock(); - } - if (isdone) { - invokeCallback(callback); - } - } + public void cancel() { + this.cancel(true); } - private static class TimeoutCheckTask implements TimerTask { - - private DefaultFuture future; - - TimeoutCheckTask(DefaultFuture future) { - this.future = future; - } - - @Override - public void run(Timeout timeout) { - if (future == null || future.isDone()) { - return; - } - // create exception response. - Response timeoutResponse = new Response(future.getId()); - // set timeout status. - timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT); - timeoutResponse.setErrorMessage(future.getTimeoutMessage(true)); - // handle response. - DefaultFuture.received(future.getChannel(), timeoutResponse); - - } - } - private void invokeCallback(ResponseCallback c) { - ResponseCallback callbackCopy = c; - if (callbackCopy == null) { - throw new NullPointerException("callback cannot be null."); - } - Response res = response; + private void doReceived(Response res) { if (res == null) { - throw new IllegalStateException("response cannot be null. url:" + channel.getUrl()); + throw new IllegalStateException("response cannot be null"); } - if (res.getStatus() == Response.OK) { - try { - callbackCopy.done(res.getResult()); - } catch (Exception e) { - logger.error("callback invoke error .result:" + res.getResult() + ",url:" + channel.getUrl(), e); - } + this.complete(res.getResult()); } else if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) { - try { - TimeoutException te = new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage()); - callbackCopy.caught(te); - } catch (Exception e) { - logger.error("callback invoke error ,url:" + channel.getUrl(), e); - } + this.completeExceptionally(new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage())); } else { - try { - RuntimeException re = new RuntimeException(res.getErrorMessage()); - callbackCopy.caught(re); - } catch (Exception e) { - logger.error("callback invoke error ,url:" + channel.getUrl(), e); - } - } - } - - private Object returnFromResponse() throws RemotingException { - Response res = response; - if (res == null) { - throw new IllegalStateException("response cannot be null"); - } - if (res.getStatus() == Response.OK) { - return res.getResult(); - } - if (res.getStatus() == Response.CLIENT_TIMEOUT || res.getStatus() == Response.SERVER_TIMEOUT) { - throw new TimeoutException(res.getStatus() == Response.SERVER_TIMEOUT, channel, res.getErrorMessage()); + this.completeExceptionally(new RemotingException(channel, res.getErrorMessage())); } - throw new RemotingException(channel, res.getErrorMessage()); } private long getId() { @@ -317,25 +192,16 @@ private int getTimeout() { return timeout; } - private long getStartTimestamp() { - return start; - } - private void doSent() { sent = System.currentTimeMillis(); } - private void doReceived(Response res) { - lock.lock(); - try { - response = res; - done.signalAll(); - } finally { - lock.unlock(); - } - if (callback != null) { - invokeCallback(callback); - } + /** + * check time out of the future + */ + private static void timeoutCheck(DefaultFuture future) { + TimeoutCheckTask task = new TimeoutCheckTask(future); + TIME_OUT_TIMER.newTimeout(task, future.getTimeout(), TimeUnit.MILLISECONDS); } private String getTimeoutMessage(boolean scan) { @@ -350,4 +216,28 @@ private String getTimeoutMessage(boolean scan) { + timeout + " ms, request: " + request + ", channel: " + channel.getLocalAddress() + " -> " + channel.getRemoteAddress(); } + + private static class TimeoutCheckTask implements TimerTask { + + private DefaultFuture future; + + TimeoutCheckTask(DefaultFuture future) { + this.future = future; + } + + @Override + public void run(Timeout timeout) { + if (future == null || future.isDone()) { + return; + } + // create exception response. + Response timeoutResponse = new Response(future.getId()); + // set timeout status. + timeoutResponse.setStatus(future.isSent() ? Response.SERVER_TIMEOUT : Response.CLIENT_TIMEOUT); + timeoutResponse.setErrorMessage(future.getTimeoutMessage(true)); + // handle response. + DefaultFuture.received(future.getChannel(), timeoutResponse); + + } + } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/SimpleFuture.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/SimpleFuture.java deleted file mode 100644 index 95b95f4ce2fc..000000000000 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/SimpleFuture.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.remoting.exchange.support; - -import org.apache.dubbo.remoting.RemotingException; -import org.apache.dubbo.remoting.exchange.ResponseCallback; -import org.apache.dubbo.remoting.exchange.ResponseFuture; - -/** - * SimpleFuture - */ -public class SimpleFuture implements ResponseFuture { - - private final Object value; - - public SimpleFuture(Object value) { - this.value = value; - } - - @Override - public Object get() throws RemotingException { - return value; - } - - @Override - public Object get(int timeoutInMillis) throws RemotingException { - return value; - } - - @Override - public void setCallback(ResponseCallback callback) { - callback.done(value); - } - - @Override - public boolean isDone() { - return true; - } - -} diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java index 4aef993a2e28..1666bbf38e71 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeChannel.java @@ -28,10 +28,10 @@ import org.apache.dubbo.remoting.exchange.ExchangeHandler; import org.apache.dubbo.remoting.exchange.Request; import org.apache.dubbo.remoting.exchange.Response; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import org.apache.dubbo.remoting.exchange.support.DefaultFuture; import java.net.InetSocketAddress; +import java.util.concurrent.CompletableFuture; /** * ExchangeReceiver @@ -97,12 +97,12 @@ public void send(Object message, boolean sent) throws RemotingException { } @Override - public ResponseFuture request(Object request) throws RemotingException { + public CompletableFuture request(Object request) throws RemotingException { return request(request, channel.getUrl().getPositiveParameter(Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT)); } @Override - public ResponseFuture request(Object request, int timeout) throws RemotingException { + public CompletableFuture request(Object request, int timeout) throws RemotingException { if (closed) { throw new RemotingException(this.getLocalAddress(), null, "Failed to send request " + request + ", cause: The channel " + this + " is closed!"); } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeClient.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeClient.java index 3e57fba90c4d..5b99079e0e1d 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeClient.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeClient.java @@ -27,10 +27,10 @@ import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.ExchangeClient; import org.apache.dubbo.remoting.exchange.ExchangeHandler; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import java.net.InetSocketAddress; import java.util.Collections; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import static org.apache.dubbo.common.utils.UrlUtils.getHeartbeat; @@ -62,7 +62,7 @@ public HeaderExchangeClient(Client client, boolean startTimer) { } @Override - public ResponseFuture request(Object request) throws RemotingException { + public CompletableFuture request(Object request) throws RemotingException { return channel.request(request); } @@ -77,7 +77,7 @@ public InetSocketAddress getRemoteAddress() { } @Override - public ResponseFuture request(Object request, int timeout) throws RemotingException { + public CompletableFuture request(Object request, int timeout) throws RemotingException { return channel.request(request, timeout); } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeHandler.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeHandler.java index 6f342f997c0c..d0f62fe6cb08 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeHandler.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/header/HeaderExchangeHandler.java @@ -34,7 +34,7 @@ import org.apache.dubbo.remoting.transport.ChannelHandlerDelegate; import java.net.InetSocketAddress; -import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionStage; /** @@ -99,19 +99,12 @@ void handleRequest(final ExchangeChannel channel, Request req) throws RemotingEx // find handler by message class. Object msg = req.getData(); try { - // handle data. - CompletableFuture future = handler.reply(channel, msg); - if (future.isDone()) { - res.setStatus(Response.OK); - res.setResult(future.get()); - channel.send(res); - return; - } - future.whenComplete((result, t) -> { + CompletionStage future = handler.reply(channel, msg); + future.whenComplete((appResult, t) -> { try { if (t == null) { res.setStatus(Response.OK); - res.setResult(result); + res.setResult(appResult); } else { res.setStatus(Response.SERVICE_ERROR); res.setErrorMessage(StringUtils.toString(t)); diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/Main.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/Main.java index 566bda10d8eb..4478f86ecfd5 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/Main.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/Main.java @@ -19,12 +19,12 @@ import org.apache.dubbo.common.URL; import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.Exchangers; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import org.apache.dubbo.remoting.exchange.support.Replier; import org.apache.dubbo.remoting.exchange.support.ReplierDispatcher; import java.io.Serializable; import java.util.Random; +import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.Executors; @@ -94,7 +94,7 @@ private static void test(int port) throws Exception { System.out.println("=====test invoke====="); for (int i = 0; i < 100; i++) { - ResponseFuture future = client.request(new Main.Data()); + CompletableFuture future = client.request(new Main.Data()); System.out.println("invoke and get"); System.out.println("invoke result:" + future.get()); } diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/PerformanceServerTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/PerformanceServerTest.java index 413aa05b657d..1989d3715c5f 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/PerformanceServerTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/PerformanceServerTest.java @@ -25,7 +25,6 @@ import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter; import org.apache.dubbo.remoting.transport.dispatcher.execution.ExecutionDispatcher; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.ArrayList; diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java index 1ab41243dd49..2dd400545a4e 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/exchange/support/DefaultFutureTest.java @@ -74,7 +74,7 @@ public void timeoutNotSend() throws Exception { try { f.get(); } catch (Exception e) { - Assertions.assertTrue(e instanceof TimeoutException, "catch exception is not timeout exception!"); + Assertions.assertTrue(e.getCause() instanceof TimeoutException, "catch exception is not timeout exception!"); System.out.println(e.getMessage()); } } @@ -108,7 +108,7 @@ public void timeoutSend() throws Exception { try { f.get(); } catch (Exception e) { - Assertions.assertTrue(e instanceof TimeoutException, "catch exception is not timeout exception!"); + Assertions.assertTrue(e.getCause() instanceof TimeoutException, "catch exception is not timeout exception!"); System.out.println(e.getMessage()); } } diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/handler/HeaderExchangeHandlerTest.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/handler/HeaderExchangeHandlerTest.java index 3c11eca1c459..d08c8e4285d2 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/handler/HeaderExchangeHandlerTest.java +++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/handler/HeaderExchangeHandlerTest.java @@ -178,7 +178,7 @@ public void send(Object message) throws RemotingException { HeaderExchangeHandler hexhandler = new HeaderExchangeHandler(new MockedExchangeHandler() { @Override - public CompletableFuture reply(ExchangeChannel channel, Object request) throws RemotingException { + public CompletableFuture reply(ExchangeChannel channel, Object request) throws RemotingException { Assertions.fail(); throw new RemotingException(channel, ""); } diff --git a/dubbo-remoting/dubbo-remoting-mina/src/test/java/org/apache/remoting/transport/mina/ClientToServerTest.java b/dubbo-remoting/dubbo-remoting-mina/src/test/java/org/apache/remoting/transport/mina/ClientToServerTest.java index 987139275d5e..6414434f51d8 100644 --- a/dubbo-remoting/dubbo-remoting-mina/src/test/java/org/apache/remoting/transport/mina/ClientToServerTest.java +++ b/dubbo-remoting/dubbo-remoting-mina/src/test/java/org/apache/remoting/transport/mina/ClientToServerTest.java @@ -19,7 +19,6 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.ExchangeServer; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import org.apache.dubbo.remoting.exchange.support.Replier; import org.junit.jupiter.api.AfterEach; @@ -27,6 +26,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.concurrent.CompletableFuture; + /** * ClientToServer */ @@ -64,7 +65,7 @@ protected void tearDown() { @Test public void testFuture() throws Exception { - ResponseFuture future = client.request(new World("world")); + CompletableFuture future = client.request(new World("world")); Hello result = (Hello) future.get(); Assertions.assertEquals("hello,world", result.getName()); } diff --git a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandlerTest.java b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandlerTest.java index 52c3e9d03e7f..da93c18c646d 100644 --- a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandlerTest.java +++ b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/exchange/support/header/HeartbeatHandlerTest.java @@ -29,6 +29,7 @@ import org.apache.dubbo.remoting.exchange.ExchangeServer; import org.apache.dubbo.remoting.exchange.Exchangers; import org.apache.dubbo.remoting.transport.dispatcher.FakeChannelHandlers; + import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; diff --git a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java index 03466bed688c..267f56940650 100644 --- a/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java +++ b/dubbo-remoting/dubbo-remoting-netty/src/test/java/org/apache/dubbo/remoting/transport/netty/ClientToServerTest.java @@ -19,14 +19,14 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.ExchangeServer; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import org.apache.dubbo.remoting.exchange.support.Replier; -import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.concurrent.CompletableFuture; + /** * ClientToServer */ @@ -64,7 +64,7 @@ protected void tearDown() throws Exception { @Test public void testFuture() throws Exception { - ResponseFuture future = client.request(new World("world")); + CompletableFuture future = client.request(new World("world")); Hello result = (Hello) future.get(); Assertions.assertEquals("hello,world", result.getName()); } diff --git a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientToServerTest.java b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientToServerTest.java index 9d2311fa5ff3..9b8db0027c25 100644 --- a/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientToServerTest.java +++ b/dubbo-remoting/dubbo-remoting-netty4/src/test/java/org/apache/dubbo/remoting/transport/netty4/ClientToServerTest.java @@ -19,7 +19,6 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.exchange.ExchangeChannel; import org.apache.dubbo.remoting.exchange.ExchangeServer; -import org.apache.dubbo.remoting.exchange.ResponseFuture; import org.apache.dubbo.remoting.exchange.support.Replier; import org.junit.jupiter.api.AfterEach; @@ -27,6 +26,8 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import java.util.concurrent.CompletableFuture; + /** * ClientToServer */ @@ -64,7 +65,7 @@ protected void tearDown() { @Test public void testFuture() throws Exception { - ResponseFuture future = client.request(new World("world")); + CompletableFuture future = client.request(new World("world")); Hello result = (Hello) future.get(); Assertions.assertEquals("hello,world", result.getName()); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java deleted file mode 100644 index b898934c63c2..000000000000 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.rpc; - -import org.apache.dubbo.common.utils.StringUtils; - -import java.util.HashMap; -import java.util.Map; - -/** - * - */ -public abstract class AbstractResult implements Result { - protected Map attachments = new HashMap(); - - protected Object result; - - protected Throwable exception; - - @Override - public Map getAttachments() { - return attachments; - } - - @Override - public void setAttachments(Map map) { - this.attachments = map == null ? new HashMap() : map; - } - - @Override - public void addAttachments(Map map) { - if (map == null) { - return; - } - if (this.attachments == null) { - this.attachments = new HashMap(); - } - this.attachments.putAll(map); - } - - @Override - public String getAttachment(String key) { - return attachments.get(key); - } - - @Override - public String getAttachment(String key, String defaultValue) { - String result = attachments.get(key); - if (StringUtils.isEmpty(result)) { - result = defaultValue; - } - return result; - } - - @Override - public void setAttachment(String key, String value) { - attachments.put(key, value); - } - -} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java new file mode 100644 index 000000000000..6ede9d4ee5be --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.rpc; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; + +/** + * {@link AsyncRpcResult} is introduced in 3.0.0 to replace RpcResult, and RpcResult is replaced with {@link AppResponse}: + *
    + *
  • AsyncRpcResult is the object that is actually passed in the call chain
  • + *
  • AppResponse only simply represents the business result
  • + *
+ * + * The relationship between them can be reflected in the definition of AsyncRpcResult: + *
+ *  {@code
+ *   Public class AsyncRpcResult implements Result {
+ *      private CompletableFuture  resultFuture;
+ *       ......
+ *   }
+ *  }
+ * 
+ * + * In theory, AppResponse does not need to implement the {@link Result} interface, this is done mainly for compatibility purpose. + * + * @serial Do not change the class name and properties. + */ +public class AppResponse implements Result, Serializable { + + private static final long serialVersionUID = -6925924956850004727L; + + private Object result; + + private Throwable exception; + + private Map attachments = new HashMap(); + + public AppResponse() { + } + + public AppResponse(Object result) { + this.result = result; + } + + public AppResponse(Throwable exception) { + this.exception = exception; + } + + @Override + public Object recreate() throws Throwable { + if (exception != null) { + throw exception; + } + return result; + } + + @Override + public Object getValue() { + return result; + } + + public void setValue(Object value) { + this.result = value; + } + + @Override + public Throwable getException() { + return exception; + } + + public void setException(Throwable e) { + this.exception = e; + } + + @Override + public boolean hasException() { + return exception != null; + } + + @Override + public Map getAttachments() { + return attachments; + } + + /** + * Append all items from the map into the attachment, if map is empty then nothing happens + * + * @param map contains all key-value pairs to append + */ + public void setAttachments(Map map) { + this.attachments = map == null ? new HashMap() : map; + } + + public void addAttachments(Map map) { + if (map == null) { + return; + } + if (this.attachments == null) { + this.attachments = new HashMap(); + } + this.attachments.putAll(map); + } + + @Override + public String getAttachment(String key) { + return attachments.get(key); + } + + @Override + public String getAttachment(String key, String defaultValue) { + String result = attachments.get(key); + if (result == null || result.length() == 0) { + result = defaultValue; + } + return result; + } + + public void setAttachment(String key, String value) { + attachments.put(key, value); + } + + @Override + public Result thenApplyWithContext(Function fn) { + throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly."); + } + + @Override + public CompletableFuture thenApply(Function fn) { + throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly."); + } + + @Override + public Result get() throws InterruptedException, ExecutionException { + throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly."); + } + + @Override + public String toString() { + return "AppResponse [value=" + result + ", exception=" + exception + "]"; + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java index b631dffe180a..e48b7130159f 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java @@ -22,96 +22,27 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; +import java.util.concurrent.ExecutionException; import java.util.function.Function; -/** - * NOTICE!! - * - *

- * You should never rely on this class directly when using or extending Dubbo, the implementation of {@link AsyncRpcResult} - * is only a workaround for compatibility purpose. It may be changed or even get removed from the next major version. - * Please only use {@link Result} or {@link RpcResult}. - * - * Extending the {@link Filter} is one typical use case: - *

- * {@code
- * public class YourFilter implements Filter {
- *     @Override
- *     public Result onResponse(Result result, Invoker invoker, Invocation invocation) {
- *         System.out.println("Filter get the return value: " + result.getValue());
- *         // Don't do this
- *         // AsyncRpcResult asyncRpcResult = ((AsyncRpcResult)result;
- *         // System.out.println("Filter get the return value: " + asyncRpcResult.getValue());
- *         return result;
- *     }
- *
- *     @Override
- *     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
- *         return invoker.invoke(invocation);
- *     }
- * }
- * }
- * 
- *

- * TODO RpcResult can be an instance of {@link java.util.concurrent.CompletionStage} instead of composing CompletionStage inside. - */ -public class AsyncRpcResult extends AbstractResult { +public class AsyncRpcResult implements Result { private static final Logger logger = LoggerFactory.getLogger(AsyncRpcResult.class); /** - * RpcContext can be changed, because thread may have been used by other thread. It should be cloned before store. - * So we use Invocation instead, Invocation will create for every invoke, but invocation only support attachments of string type. + * RpcContext may already have been changed when callback happens, it happens when the same thread is used to execute another RPC call. + * So we should keep the reference of current RpcContext instance and restore it before callback being executed. */ private RpcContext storedContext; private RpcContext storedServerContext; - protected CompletableFuture valueFuture; + private CompletableFuture responseFuture; + private Invocation invocation; - protected CompletableFuture resultFuture; - - public AsyncRpcResult(CompletableFuture future) { - this(future, true); - } - - public AsyncRpcResult(CompletableFuture future, boolean registerCallback) { - this(future, new CompletableFuture<>(), registerCallback); - } - - /** - * @param future - * @param rFuture - * @param registerCallback - */ - public AsyncRpcResult(CompletableFuture future, final CompletableFuture rFuture, boolean registerCallback) { - if (rFuture == null) { - throw new IllegalArgumentException(); - } - resultFuture = rFuture; - if (registerCallback) { - /** - * We do not know whether future already completed or not, it's a future exposed or even created by end user. - * 1. future complete before whenComplete. whenComplete fn (resultFuture.complete) will be executed in thread subscribing, in our case, it's Dubbo thread. - * 2. future complete after whenComplete. whenComplete fn (resultFuture.complete) will be executed in thread calling complete, normally its User thread. - */ - future.whenComplete((v, t) -> { - RpcResult rpcResult; - if (t != null) { - if (t instanceof CompletionException) { - rpcResult = new RpcResult(t.getCause()); - } else { - rpcResult = new RpcResult(t); - } - } else { - rpcResult = new RpcResult(v); - } - // instead of resultFuture we must use rFuture here, resultFuture may being changed before complete when building filter chain, but rFuture was guaranteed never changed by closure. - rFuture.complete(rpcResult); - }); - } - this.valueFuture = future; - // employ copy of context avoid the other call may modify the context content - this.storedContext = RpcContext.getContext().copyOf(); - this.storedServerContext = RpcContext.getServerContext().copyOf(); + public AsyncRpcResult(CompletableFuture future, Invocation invocation) { + this.responseFuture = future; + this.invocation = invocation; + this.storedContext = RpcContext.getContext(); + this.storedServerContext = RpcContext.getServerContext(); } @Override @@ -120,51 +51,86 @@ public Object getValue() { } @Override - public Throwable getException() { - return getRpcResult().getException(); + public void setValue(Object value) { + } @Override - public boolean hasException() { - return getRpcResult().hasException(); + public Throwable getException() { + return getRpcResult().getException(); } @Override - public Object getResult() { - return getRpcResult().getResult(); + public void setException(Throwable t) { + } - public CompletableFuture getValueFuture() { - return valueFuture; + @Override + public boolean hasException() { + return getRpcResult().hasException(); } - public CompletableFuture getResultFuture() { - return resultFuture; + public CompletableFuture getResponseFuture() { + return responseFuture; } - public void setResultFuture(CompletableFuture resultFuture) { - this.resultFuture = resultFuture; + public void setResponseFuture(CompletableFuture responseFuture) { + this.responseFuture = responseFuture; } public Result getRpcResult() { try { - if (resultFuture.isDone()) { - return resultFuture.get(); + if (responseFuture.isDone()) { + return responseFuture.get(); } } catch (Exception e) { // This should never happen; logger.error("Got exception when trying to fetch the underlying result from AsyncRpcResult.", e); } - return new RpcResult(); + return new AppResponse(); } @Override public Object recreate() throws Throwable { - return valueFuture; + RpcInvocation rpcInvocation = (RpcInvocation) invocation; + if (InvokeMode.FUTURE == rpcInvocation.getInvokeMode()) { + AppResponse rpcResult = new AppResponse(); + CompletableFuture future = new CompletableFuture<>(); + rpcResult.setValue(future); + responseFuture.whenComplete((result, t) -> { + if (t != null) { + if (t instanceof CompletionException) { + t = t.getCause(); + } + future.completeExceptionally(t); + } else { + if (result.hasException()) { + future.completeExceptionally(result.getException()); + } else { + future.complete(result.getValue()); + } + } + }); + return rpcResult.recreate(); + } else if (responseFuture.isDone()) { + return responseFuture.get().recreate(); + } + return (new AppResponse()).recreate(); } - public void thenApplyWithContext(Function fn) { - this.resultFuture = resultFuture.thenApply(fn.compose(beforeContext).andThen(afterContext)); + public Result get() throws InterruptedException, ExecutionException { + return responseFuture.get(); + } + + @Override + public Result thenApplyWithContext(Function fn) { + this.responseFuture = responseFuture.thenApply(fn.compose(beforeContext).andThen(afterContext)); + return this; + } + + @Override + public CompletableFuture thenApply(Function fn) { + return this.responseFuture.thenApply(fn); } @Override @@ -203,18 +169,49 @@ public void setAttachment(String key, String value) { private RpcContext tmpContext; private RpcContext tmpServerContext; - private Function beforeContext = (result) -> { + private Function beforeContext = (appResponse) -> { tmpContext = RpcContext.getContext(); tmpServerContext = RpcContext.getServerContext(); RpcContext.restoreContext(storedContext); RpcContext.restoreServerContext(storedServerContext); - return result; + return appResponse; }; - private Function afterContext = (result) -> { + private Function afterContext = (appResponse) -> { RpcContext.restoreContext(tmpContext); RpcContext.restoreServerContext(tmpServerContext); - return result; + return appResponse; }; + + /** + * Some utility methods used to quickly generate default AsyncRpcResult instance. + */ + public static AsyncRpcResult newDefaultAsyncResult(AppResponse result, Invocation invocation) { + return new AsyncRpcResult(CompletableFuture.completedFuture(result), invocation); + } + + public static AsyncRpcResult newDefaultAsyncResult(Invocation invocation) { + return newDefaultAsyncResult(null, null, invocation); + } + + public static AsyncRpcResult newDefaultAsyncResult(Object value, Invocation invocation) { + return newDefaultAsyncResult(value, null, invocation); + } + + public static AsyncRpcResult newDefaultAsyncResult(Throwable t, Invocation invocation) { + return newDefaultAsyncResult(null, t, invocation); + } + + public static AsyncRpcResult newDefaultAsyncResult(Object value, Throwable t, Invocation invocation) { + CompletableFuture future = new CompletableFuture<>(); + AppResponse result = new AppResponse(); + if (t != null) { + result.setException(t); + } else { + result.setValue(value); + } + future.complete(result); + return new AsyncRpcResult(future, invocation); + } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java index a17fd906d554..7c634481d7e5 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java @@ -42,35 +42,16 @@ */ @SPI public interface Filter { - /** - * do invoke filter. - *

- * - * // before filter - * Result result = invoker.invoke(invocation); - * // after filter - * return result; - * - * - * @param invoker service - * @param invocation invocation. - * @return invoke result. - * @throws RpcException - * @see org.apache.dubbo.rpc.Invoker#invoke(Invocation) + * Does not need to override/implement this method. */ Result invoke(Invoker invoker, Invocation invocation) throws RpcException; - /** - * Return processing result - * - * @param result result - * @param invoker invoker - * @param invocation invocation - * @return Return {@link Result} - */ - default Result onResponse(Result result, Invoker invoker, Invocation invocation) { - return result; + interface Listener { + + void onResponse(Result result, Invoker invoker, Invocation invocation); + + void onError(Throwable t, Invoker invoker, Invocation invocation); } } \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java new file mode 100644 index 000000000000..2468837958ce --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java @@ -0,0 +1,52 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.rpc; + +import java.util.concurrent.CompletableFuture; + +/** + * Used for async call scenario. But if the method you are calling has a {@link CompletableFuture} signature + * you do not need to use this class since you will get a Future response directly. + *

+ * Remember to save the Future reference before making another call using the same thread, otherwise, + * the current Future will be override by the new one, which means you will lose the chance get the return value. + */ +public class FutureContext { + + public static ThreadLocal> futureTL = new ThreadLocal<>(); + + /** + * get future. + * + * @param + * @return future + */ + @SuppressWarnings("unchecked") + public static CompletableFuture getCompletableFuture() { + return (CompletableFuture) futureTL.get(); + } + + /** + * set future. + * + * @param future + */ + public static void setFuture(CompletableFuture future) { + futureTL.set(future); + } + +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java index 2b5f3dd9e958..058e0ad09c9a 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Invocation.java @@ -59,6 +59,10 @@ public interface Invocation { */ Map getAttachments(); + void setAttachment(String key, String value); + + void setAttachmentIfAbsent(String key, String value); + /** * get attachment by key. * diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/InvokeMode.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/InvokeMode.java new file mode 100644 index 000000000000..a97a0be61f4f --- /dev/null +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/InvokeMode.java @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.rpc; + +public enum InvokeMode { + + SYNC, ASYNC, FUTURE; + +} diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseCallback.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ListenableFilter.java similarity index 71% rename from dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseCallback.java rename to dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ListenableFilter.java index 37fe6cc6e342..622ef1f0309f 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/ResponseCallback.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/ListenableFilter.java @@ -1,38 +1,29 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.remoting.exchange; - -/** - * Callback - */ -public interface ResponseCallback { - - /** - * done. - * - * @param response - */ - void done(Object response); - - /** - * caught exception. - * - * @param exception - */ - void caught(Throwable exception); - -} \ No newline at end of file +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.dubbo.rpc; + +/** + * + */ +public abstract class ListenableFilter implements Filter { + + protected Listener listener = null; + + public Listener listener() { + return listener; + } +} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java index 58a258241ff9..1ecd9dae7715 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java @@ -18,6 +18,9 @@ import java.io.Serializable; import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.function.Function; /** @@ -25,7 +28,7 @@ * * @serial Don't change the class name and package name. * @see org.apache.dubbo.rpc.Invoker#invoke(Invocation) - * @see org.apache.dubbo.rpc.RpcResult + * @see AppResponse */ public interface Result extends Serializable { @@ -36,6 +39,8 @@ public interface Result extends Serializable { */ Object getValue(); + void setValue(Object value); + /** * Get exception. * @@ -43,6 +48,8 @@ public interface Result extends Serializable { */ Throwable getException(); + void setException(Throwable t); + /** * Has exception. * @@ -66,14 +73,6 @@ public interface Result extends Serializable { */ Object recreate() throws Throwable; - /** - * @see org.apache.dubbo.rpc.Result#getValue() - * @deprecated Replace to getValue() - */ - @Deprecated - Object getResult(); - - /** * get attachments. * @@ -111,4 +110,10 @@ public interface Result extends Serializable { void setAttachment(String key, String value); + Result thenApplyWithContext(Function fn); + + CompletableFuture thenApply(Function fn); + + Result get() throws InterruptedException, ExecutionException; + } \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java index fa63b7e4c1a3..c585c178ce92 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcContext.java @@ -70,7 +70,6 @@ protected RpcContext initialValue() { private final Map attachments = new HashMap(); private final Map values = new HashMap(); - private Future future; private List urls; @@ -139,32 +138,6 @@ public static void restoreContext(RpcContext oldContext) { LOCAL.set(oldContext); } - - public RpcContext copyOf() { - RpcContext copy = new RpcContext(); - copy.attachments.putAll(this.attachments); - copy.values.putAll(this.values); - copy.future = this.future; - copy.urls = this.urls; - copy.url = this.url; - copy.methodName = this.methodName; - copy.parameterTypes = this.parameterTypes; - copy.arguments = this.arguments; - copy.localAddress = this.localAddress; - copy.remoteAddress = this.remoteAddress; - copy.remoteApplicationName = this.remoteApplicationName; - copy.invokers = this.invokers; - copy.invoker = this.invoker; - copy.invocation = this.invocation; - - copy.request = this.request; - copy.response = this.response; - copy.asyncContext = this.asyncContext; - - return copy; - } - - /** * remove context. * @@ -246,7 +219,7 @@ public boolean isConsumerSide() { */ @SuppressWarnings("unchecked") public CompletableFuture getCompletableFuture() { - return (CompletableFuture) future; + return FutureContext.getCompletableFuture(); } /** @@ -257,7 +230,7 @@ public CompletableFuture getCompletableFuture() { */ @SuppressWarnings("unchecked") public Future getFuture() { - return (Future) future; + return FutureContext.getCompletableFuture(); } /** @@ -265,8 +238,8 @@ public Future getFuture() { * * @param future */ - public void setFuture(Future future) { - this.future = future; + public void setFuture(CompletableFuture future) { + FutureContext.setFuture(future); } public List getUrls() { diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java index 707bf3b77adf..207239d11ef6 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcInvocation.java @@ -45,6 +45,10 @@ public class RpcInvocation implements Invocation, Serializable { private transient Invoker invoker; + private transient Class returnType; + + private transient InvokeMode invokeMode; + public RpcInvocation() { } @@ -87,6 +91,7 @@ public RpcInvocation(Method method, Object[] arguments) { public RpcInvocation(Method method, Object[] arguments, Map attachment) { this(method.getName(), method.getParameterTypes(), arguments, attachment, null); + this.returnType = method.getReturnType(); } public RpcInvocation(String methodName, Class[] parameterTypes, Object[] arguments) { @@ -205,6 +210,22 @@ public String getAttachment(String key, String defaultValue) { return value; } + public Class getReturnType() { + return returnType; + } + + public void setReturnType(Class returnType) { + this.returnType = returnType; + } + + public InvokeMode getInvokeMode() { + return invokeMode; + } + + public void setInvokeMode(InvokeMode invokeMode) { + this.invokeMode = invokeMode; + } + @Override public String toString() { return "RpcInvocation [methodName=" + methodName + ", parameterTypes=" diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcResult.java deleted file mode 100644 index 8087210f29aa..000000000000 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/RpcResult.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.rpc; - -import java.lang.reflect.Field; - -/** - * RPC Result. - * - * @serial Don't change the class name and properties. - */ -public class RpcResult extends AbstractResult { - - private static final long serialVersionUID = -6925924956850004727L; - - public RpcResult() { - } - - public RpcResult(Object result) { - this.result = result; - } - - public RpcResult(Throwable exception) { - this.exception = handleStackTraceNull(exception); - } - - @Override - public Object recreate() throws Throwable { - if (exception != null) { - throw exception; - } - return result; - } - - /** - * @see org.apache.dubbo.rpc.RpcResult#getValue() - * @deprecated Replace to getValue() - */ - @Override - @Deprecated - public Object getResult() { - return getValue(); - } - - /** - * @see org.apache.dubbo.rpc.RpcResult#setValue(Object) - * @deprecated Replace to setValue() - */ - @Deprecated - public void setResult(Object result) { - setValue(result); - } - - @Override - public Object getValue() { - return result; - } - - public void setValue(Object value) { - this.result = value; - } - - @Override - public Throwable getException() { - return exception; - } - - public void setException(Throwable e) { - this.exception = handleStackTraceNull(e); - } - - @Override - public boolean hasException() { - return exception != null; - } - - @Override - public String toString() { - return "RpcResult [result=" + result + ", exception=" + exception + "]"; - } - - /** - * we need to deal the exception whose stack trace is null. - *

- * see https://github.com/apache/incubator-dubbo/pull/2956 - * and https://github.com/apache/incubator-dubbo/pull/3634 - * and https://github.com/apache/incubator-dubbo/issues/619 - * - * @param e exception - * @return exception after deal with stack trace - */ - private Throwable handleStackTraceNull(Throwable e) { - if (e != null) { - try { - // get Throwable class - Class clazz = e.getClass(); - while (!clazz.getName().equals(Throwable.class.getName())) { - clazz = clazz.getSuperclass(); - } - // get stackTrace value - Field stackTraceField = clazz.getDeclaredField("stackTrace"); - stackTraceField.setAccessible(true); - Object stackTrace = stackTraceField.get(e); - if (stackTrace == null) { - e.setStackTrace(new StackTraceElement[0]); - } - } catch (Throwable t) { - // ignore - } - } - - return e; - } -} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/SimpleAsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/SimpleAsyncRpcResult.java deleted file mode 100644 index 98e42d94a382..000000000000 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/SimpleAsyncRpcResult.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.rpc; - -import java.util.concurrent.CompletableFuture; - -/** - * A sub class used for normal async invoke. - * - * NOTICE!! - * - *

- * You should never rely on this class directly when using or extending Dubbo, the implementation of {@link SimpleAsyncRpcResult} - * is only a workaround for compatibility purpose. It may be changed or even get removed from the next major version. - * Please only use {@link Result} or {@link RpcResult}. - *

- * - * Check {@link AsyncRpcResult} for more details. - * - * TODO AsyncRpcResult, AsyncNormalRpcResult should not be a parent-child hierarchy. - */ -public class SimpleAsyncRpcResult extends AsyncRpcResult { - public SimpleAsyncRpcResult(CompletableFuture future, boolean registerCallback) { - super(future, registerCallback); - } - - public SimpleAsyncRpcResult(CompletableFuture future, CompletableFuture rFuture, boolean registerCallback) { - super(future, rFuture, registerCallback); - } - - @Override - public Object recreate() throws Throwable { - // TODO should we check the status of valueFuture here? - return null; - } -} diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java index 1c2f69fecb96..fe692af565f7 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java @@ -19,14 +19,17 @@ import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; +import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; +import org.apache.dubbo.rpc.ListenableFilter; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcStatus; /** + * * ActiveLimitFilter restrict the concurrent client invocation for a service or service's method from client side. * To use active limit filter, configured url with actives and provide valid >0 integer value. *
@@ -39,50 +42,75 @@
  * @see Filter
  */
 @Activate(group = Constants.CONSUMER, value = Constants.ACTIVES_KEY)
-public class ActiveLimitFilter implements Filter {
+public class ActiveLimitFilter extends ListenableFilter {
+
+    private static final String ACTIVELIMIT_FILTER_START_TIME = "activelimit_filter_start_time";
+
+    public ActiveLimitFilter() {
+        super.listener = new ActiveLimitListener();
+    }
 
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
         URL url = invoker.getUrl();
         String methodName = invocation.getMethodName();
         int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
-        RpcStatus count = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName());
-        if (!count.beginCount(url, methodName, max)) {
+        RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName());
+        if (!RpcStatus.beginCount(url, methodName, max)) {
             long timeout = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, 0);
             long start = System.currentTimeMillis();
             long remain = timeout;
-            synchronized (count) {
-                while (!count.beginCount(url, methodName, max)) {
+            synchronized (rpcStatus) {
+                while (!RpcStatus.beginCount(url, methodName, max)) {
                     try {
-                        count.wait(remain);
+                        rpcStatus.wait(remain);
                     } catch (InterruptedException e) {
                         // ignore
                     }
                     long elapsed = System.currentTimeMillis() - start;
                     remain = timeout - elapsed;
                     if (remain <= 0) {
-                        throw new RpcException("Waiting concurrent invoke timeout in client-side for service:  "
-                                + invoker.getInterface().getName() + ", method: "
-                                + invocation.getMethodName() + ", elapsed: " + elapsed
-                                + ", timeout: " + timeout + ". concurrent invokes: " + count.getActive()
-                                + ". max concurrent invoke limit: " + max);
+                        throw new RpcException("Waiting concurrent invoke timeout in client-side for service:  " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", elapsed: " + elapsed + ", timeout: " + timeout + ". concurrent invokes: " + rpcStatus.getActive() + ". max concurrent invoke limit: " + max);
                     }
                 }
             }
         }
 
-        boolean isSuccess = true;
-        long begin = System.currentTimeMillis();
-        try {
-            return invoker.invoke(invocation);
-        } catch (RuntimeException t) {
-            isSuccess = false;
-            throw t;
-        } finally {
-            count.endCount(url, methodName, System.currentTimeMillis() - begin, isSuccess);
+        invocation.setAttachment(ACTIVELIMIT_FILTER_START_TIME, String.valueOf(System.currentTimeMillis()));
+
+        return invoker.invoke(invocation);
+    }
+
+    static class ActiveLimitListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            String methodName = invocation.getMethodName();
+            URL url = invoker.getUrl();
+            int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
+
+            RpcStatus.endCount(url, methodName, getElapsed(invocation), true);
+            notifyFinish(RpcStatus.getStatus(url, methodName), max);
+        }
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+            String methodName = invocation.getMethodName();
+            URL url = invoker.getUrl();
+            int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
+
+            RpcStatus.endCount(url, methodName, getElapsed(invocation), false);
+            notifyFinish(RpcStatus.getStatus(url, methodName), max);
+        }
+
+        private long getElapsed(Invocation invocation) {
+            String beginTime = invocation.getAttachment(ACTIVELIMIT_FILTER_START_TIME);
+            return StringUtils.isNotEmpty(beginTime) ? System.currentTimeMillis() - Long.parseLong(beginTime) : 0;
+        }
+
+        private void notifyFinish(RpcStatus rpcStatus, int max) {
             if (max > 0) {
-                synchronized (count) {
-                    count.notifyAll();
+                synchronized (rpcStatus) {
+                    rpcStatus.notifyAll();
                 }
             }
         }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
index ace832ca33cb..ad1a8a2492b5 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
@@ -24,9 +24,9 @@
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -45,44 +45,54 @@
  * @see Filter
  *
  */
-public class CompatibleFilter implements Filter {
+public class CompatibleFilter extends ListenableFilter {
 
     private static Logger logger = LoggerFactory.getLogger(CompatibleFilter.class);
 
+    public CompatibleFilter() {
+        super.listener = new CompatibleListener();
+    }
+
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
-        Result result = invoker.invoke(invocation);
-        if (!invocation.getMethodName().startsWith("$") && !result.hasException()) {
-            Object value = result.getValue();
-            if (value != null) {
-                try {
-                    Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
-                    Class type = method.getReturnType();
-                    Object newValue;
-                    String serialization = invoker.getUrl().getParameter(Constants.SERIALIZATION_KEY);
-                    if ("json".equals(serialization)
-                            || "fastjson".equals(serialization)) {
-                        // If the serialization key is json or fastjson
-                        Type gtype = method.getGenericReturnType();
-                        newValue = PojoUtils.realize(value, type, gtype);
-                    } else if (!type.isInstance(value)) {
-                        //if local service interface's method's return type is not instance of return value
-                        newValue = PojoUtils.isPojo(type)
-                                ? PojoUtils.realize(value, type)
-                                : CompatibleTypeUtils.compatibleTypeConvert(value, type);
+        return invoker.invoke(invocation);
+    }
 
-                    } else {
-                        newValue = value;
-                    }
-                    if (newValue != value) {
-                        result = new RpcResult(newValue);
+    static class CompatibleListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            if (!invocation.getMethodName().startsWith("$") && !result.hasException()) {
+                Object value = result.getValue();
+                if (value != null) {
+                    try {
+                        Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
+                        Class type = method.getReturnType();
+                        Object newValue;
+                        String serialization = invoker.getUrl().getParameter(Constants.SERIALIZATION_KEY);
+                        if ("json".equals(serialization) || "fastjson".equals(serialization)) {
+                            // If the serialization key is json or fastjson
+                            Type gtype = method.getGenericReturnType();
+                            newValue = PojoUtils.realize(value, type, gtype);
+                        } else if (!type.isInstance(value)) {
+                            //if local service interface's method's return type is not instance of return value
+                            newValue = PojoUtils.isPojo(type) ? PojoUtils.realize(value, type) : CompatibleTypeUtils.compatibleTypeConvert(value, type);
+
+                        } else {
+                            newValue = value;
+                        }
+                        if (newValue != value) {
+                            result.setValue(newValue);
+                        }
+                    } catch (Throwable t) {
+                        logger.warn(t.getMessage(), t);
                     }
-                } catch (Throwable t) {
-                    logger.warn(t.getMessage(), t);
                 }
             }
         }
-        return result;
-    }
 
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
+    }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
index 5db6b889d35e..a2005e21e1a3 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
@@ -19,9 +19,9 @@
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.utils.NetUtils;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
@@ -35,7 +35,11 @@
  * @see RpcContext
  */
 @Activate(group = Constants.CONSUMER, order = -10000)
-public class ConsumerContextFilter implements Filter {
+public class ConsumerContextFilter extends ListenableFilter {
+
+    public ConsumerContextFilter() {
+        super.listener = new ConsumerContextListener();
+    }
 
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
@@ -49,18 +53,22 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
             ((RpcInvocation) invocation).setInvoker(invoker);
         }
         try {
-            // TODO should we clear server context?
             RpcContext.removeServerContext();
             return invoker.invoke(invocation);
         } finally {
-            // TODO removeContext? but we need to save future for RpcContext.getFuture() API. If clear attachments here, attachments will not available when postProcessResult is invoked.
-            RpcContext.getContext().clearAttachments();
+            RpcContext.removeContext();
         }
     }
 
-    @Override
-    public Result onResponse(Result result, Invoker invoker, Invocation invocation) {
-        RpcContext.getServerContext().setAttachments(result.getAttachments());
-        return result;
+    static class ConsumerContextListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            RpcContext.getServerContext().setAttachments(result.getAttachments());
+        }
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
index fe85da0386a1..df135a648948 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
@@ -18,9 +18,9 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
@@ -38,7 +38,11 @@
  * @see RpcContext
  */
 @Activate(group = Constants.PROVIDER, order = -10000)
-public class ContextFilter implements Filter {
+public class ContextFilter extends ListenableFilter {
+
+    public ContextFilter() {
+        super.listener = new ContextListener();
+    }
 
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
@@ -86,10 +90,16 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
         }
     }
 
-    @Override
-    public Result onResponse(Result result, Invoker invoker, Invocation invocation) {
-        // pass attachments to result
-        result.addAttachments(RpcContext.getServerContext().getAttachments());
-        return result;
+    static class ContextListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            // pass attachments to result
+            result.addAttachments(RpcContext.getServerContext().getAttachments());
+        }
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java
index cba9e7f4f46c..7e3e5b8dda01 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java
@@ -18,12 +18,12 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.extension.Activate;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 
 /**
  * Dubbo provided default Echo echo service, which is available for all dubbo provider service interface.
@@ -34,7 +34,7 @@ public class EchoFilter implements Filter {
     @Override
     public Result invoke(Invoker invoker, Invocation inv) throws RpcException {
         if (inv.getMethodName().equals(Constants.$ECHO) && inv.getArguments() != null && inv.getArguments().length == 1) {
-            return new RpcResult(inv.getArguments()[0]);
+            return AsyncRpcResult.newDefaultAsyncResult(inv.getArguments()[0], inv);
         }
         return invoker.invoke(inv);
     }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
index 7715348f827c..1cb9f87d4887 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
@@ -22,13 +22,12 @@
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.service.GenericService;
 
 import java.lang.reflect.Method;
@@ -45,85 +44,82 @@
  * 
  */
 @Activate(group = Constants.PROVIDER)
-public class ExceptionFilter implements Filter {
-
-    private final Logger logger;
+public class ExceptionFilter extends ListenableFilter {
 
     public ExceptionFilter() {
-        this(LoggerFactory.getLogger(ExceptionFilter.class));
-    }
-
-    public ExceptionFilter(Logger logger) {
-        this.logger = logger;
+        super.listener = new ExceptionListener();
     }
 
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
-        try {
-            return invoker.invoke(invocation);
-        } catch (RuntimeException e) {
-            logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
-                    + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
-                    + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
-            throw e;
-        }
+        return invoker.invoke(invocation);
     }
 
-    @Override
-    public Result onResponse(Result result, Invoker invoker, Invocation invocation) {
-        if (result.hasException() && GenericService.class != invoker.getInterface()) {
-            try {
-                Throwable exception = result.getException();
-
-                // directly throw if it's checked exception
-                if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
-                    return result;
-                }
-                // directly throw if the exception appears in the signature
+    static class ExceptionListener implements Listener {
+
+        private Logger logger = LoggerFactory.getLogger(ExceptionListener.class);
+
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            if (result.hasException() && GenericService.class != invoker.getInterface()) {
                 try {
-                    Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
-                    Class[] exceptionClassses = method.getExceptionTypes();
-                    for (Class exceptionClass : exceptionClassses) {
-                        if (exception.getClass().equals(exceptionClass)) {
-                            return result;
+                    Throwable exception = result.getException();
+
+                    // directly throw if it's checked exception
+                    if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
+                        return;
+                    }
+                    // directly throw if the exception appears in the signature
+                    try {
+                        Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
+                        Class[] exceptionClassses = method.getExceptionTypes();
+                        for (Class exceptionClass : exceptionClassses) {
+                            if (exception.getClass().equals(exceptionClass)) {
+                                return;
+                            }
                         }
+                    } catch (NoSuchMethodException e) {
+                        return;
                     }
-                } catch (NoSuchMethodException e) {
-                    return result;
-                }
 
-                // for the exception not found in method's signature, print ERROR message in server's log.
-                logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost()
-                        + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
-                        + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
+                    // for the exception not found in method's signature, print ERROR message in server's log.
+                    logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + exception.getClass().getName() + ": " + exception.getMessage(), exception);
 
-                // directly throw if exception class and interface class are in the same jar file.
-                String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
-                String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
-                if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
-                    return result;
-                }
-                // directly throw if it's JDK exception
-                String className = exception.getClass().getName();
-                if (className.startsWith("java.") || className.startsWith("javax.")) {
-                    return result;
-                }
-                // directly throw if it's dubbo exception
-                if (exception instanceof RpcException) {
-                    return result;
-                }
+                    // directly throw if exception class and interface class are in the same jar file.
+                    String serviceFile = ReflectUtils.getCodeBase(invoker.getInterface());
+                    String exceptionFile = ReflectUtils.getCodeBase(exception.getClass());
+                    if (serviceFile == null || exceptionFile == null || serviceFile.equals(exceptionFile)) {
+                        return;
+                    }
+                    // directly throw if it's JDK exception
+                    String className = exception.getClass().getName();
+                    if (className.startsWith("java.") || className.startsWith("javax.")) {
+                        return;
+                    }
+                    // directly throw if it's dubbo exception
+                    if (exception instanceof RpcException) {
+                        return;
+                    }
 
-                // otherwise, wrap with RuntimeException and throw back to the client
-                return new RpcResult(new RuntimeException(StringUtils.toString(exception)));
-            } catch (Throwable e) {
-                logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost()
-                        + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName()
-                        + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
-                return result;
+                    // otherwise, wrap with RuntimeException and throw back to the client
+                    result.setException(new RuntimeException(StringUtils.toString(exception)));
+                    return;
+                } catch (Throwable e) {
+                    logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
+                    return;
+                }
             }
         }
-        return result;
-    }
 
+        @Override
+        public void onError(Throwable e, Invoker invoker, Invocation invocation) {
+            logger.error("Got unchecked and undeclared exception which called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
+        }
+
+        // For test purpose
+        public void setLogger(Logger logger) {
+            this.logger = logger;
+        }
+    }
 }
 
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java
index b335a4141ff4..c1b2eb5e6bc7 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java
@@ -19,21 +19,29 @@
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.Activate;
-import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcStatus;
 
 /**
+ *
  * The maximum parallel execution request count per method per service for the provider.If the max configured
  * executes is set to 10 and if invoke request where it is already 10 then it will throws exception. It
  * continue the same behaviour un till it is <10.
  *
  */
 @Activate(group = Constants.PROVIDER, value = Constants.EXECUTES_KEY)
-public class ExecuteLimitFilter implements Filter {
+public class ExecuteLimitFilter extends ListenableFilter {
+
+    private static final String EXECUTELIMIT_FILTER_START_TIME = "execugtelimit_filter_start_time";
+
+    public ExecuteLimitFilter() {
+        super.listener = new ExecuteLimitListener();
+    }
 
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
@@ -46,20 +54,32 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
                     "\" /> limited.");
         }
 
-        long begin = System.currentTimeMillis();
-        boolean isSuccess = true;
+        invocation.setAttachment(EXECUTELIMIT_FILTER_START_TIME, String.valueOf(System.currentTimeMillis()));
         try {
             return invoker.invoke(invocation);
         } catch (Throwable t) {
-            isSuccess = false;
             if (t instanceof RuntimeException) {
                 throw (RuntimeException) t;
             } else {
                 throw new RpcException("unexpected exception when ExecuteLimitFilter", t);
             }
-        } finally {
-            RpcStatus.endCount(url, methodName, System.currentTimeMillis() - begin, isSuccess);
         }
     }
 
+    static class ExecuteLimitListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            RpcStatus.endCount(invoker.getUrl(), invocation.getMethodName(), getElapsed(invocation), true);
+        }
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+            RpcStatus.endCount(invoker.getUrl(), invocation.getMethodName(), getElapsed(invocation), false);
+        }
+
+        private long getElapsed(Invocation invocation) {
+            String beginTime = invocation.getAttachment(EXECUTELIMIT_FILTER_START_TIME);
+            return StringUtils.isNotEmpty(beginTime) ? System.currentTimeMillis() - Long.parseLong(beginTime) : 0;
+        }
+    }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
index ae7b92c40f1e..5c86cae65779 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
@@ -28,14 +28,13 @@
 import org.apache.dubbo.common.utils.PojoUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.service.GenericException;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
@@ -47,11 +46,15 @@
  * GenericInvokerFilter.
  */
 @Activate(group = Constants.PROVIDER, order = -20000)
-public class GenericFilter implements Filter {
+public class GenericFilter extends ListenableFilter {
+
+    public GenericFilter() {
+        super.listener = new GenericListener();
+    }
 
     @Override
     public Result invoke(Invoker invoker, Invocation inv) throws RpcException {
-        if (inv.getMethodName().equals(Constants.$INVOKE)
+        if ((inv.getMethodName().equals(Constants.$INVOKE) || inv.getMethodName().equals(Constants.$INVOKE_ASYNC))
                 && inv.getArguments() != null
                 && inv.getArguments().length == 3
                 && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
@@ -108,33 +111,52 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException {
                         }
                     }
                 }
-                Result result = invoker.invoke(new RpcInvocation(method, args, inv.getAttachments()));
-                if (result.hasException()
-                        && !(result.getException() instanceof GenericException)) {
-                    return new RpcResult(new GenericException(result.getException()));
+                return invoker.invoke(new RpcInvocation(method, args, inv.getAttachments()));
+            } catch (NoSuchMethodException e) {
+                throw new RpcException(e.getMessage(), e);
+            } catch (ClassNotFoundException e) {
+                throw new RpcException(e.getMessage(), e);
+            }
+        }
+        return invoker.invoke(inv);
+    }
+
+    static class GenericListener implements Listener {
+
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation inv) {
+            if ((inv.getMethodName().equals(Constants.$INVOKE) || inv.getMethodName().equals(Constants.$INVOKE_ASYNC))
+                    && inv.getArguments() != null
+                    && inv.getArguments().length == 3
+                    && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
+
+                String generic = inv.getAttachment(Constants.GENERIC_KEY);
+                if (StringUtils.isBlank(generic)) {
+                    generic = RpcContext.getContext().getAttachment(Constants.GENERIC_KEY);
+                }
+
+                if (result.hasException() && !(result.getException() instanceof GenericException)) {
+                    result.setException(new GenericException(result.getException()));
                 }
                 if (ProtocolUtils.isJavaGenericSerialization(generic)) {
                     try {
                         UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
-                        ExtensionLoader.getExtensionLoader(Serialization.class)
-                                .getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA)
-                                .serialize(null, os).writeObject(result.getValue());
-                        return new RpcResult(os.toByteArray());
+                        ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA).serialize(null, os).writeObject(result.getValue());
+                        result.setValue(os.toByteArray());
                     } catch (IOException e) {
                         throw new RpcException("Serialize result failed.", e);
                     }
                 } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
-                    return new RpcResult(JavaBeanSerializeUtil.serialize(result.getValue(), JavaBeanAccessor.METHOD));
+                    result.setValue(JavaBeanSerializeUtil.serialize(result.getValue(), JavaBeanAccessor.METHOD));
                 } else {
-                    return new RpcResult(PojoUtils.generalize(result.getValue()));
+                    result.setValue(PojoUtils.generalize(result.getValue()));
                 }
-            } catch (NoSuchMethodException e) {
-                throw new RpcException(e.getMessage(), e);
-            } catch (ClassNotFoundException e) {
-                throw new RpcException(e.getMessage(), e);
             }
         }
-        return invoker.invoke(inv);
-    }
 
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
+    }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
index 6df1262fbef0..f9caf44f069b 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
@@ -25,37 +25,42 @@
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.PojoUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.service.GenericException;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
+import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.Type;
 
 /**
  * GenericImplInvokerFilter
  */
 @Activate(group = Constants.CONSUMER, value = Constants.GENERIC_KEY, order = 20000)
-public class GenericImplFilter implements Filter {
+public class GenericImplFilter extends ListenableFilter {
 
     private static final Logger logger = LoggerFactory.getLogger(GenericImplFilter.class);
 
     private static final Class[] GENERIC_PARAMETER_TYPES = new Class[]{String.class, String[].class, Object[].class};
 
+    public GenericImplFilter() {
+        super.listener = new GenericImplListener();
+    }
+
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
         String generic = invoker.getUrl().getParameter(Constants.GENERIC_KEY);
         if (ProtocolUtils.isGeneric(generic)
-                && !Constants.$INVOKE.equals(invocation.getMethodName())
+                && (!Constants.$INVOKE.equals(invocation.getMethodName()) && !Constants.$INVOKE_ASYNC.equals(invocation.getMethodName()))
                 && invocation instanceof RpcInvocation) {
-            RpcInvocation invocation2 = (RpcInvocation) invocation;
+            RpcInvocation invocation2 = new RpcInvocation(invocation);
             String methodName = invocation2.getMethodName();
             Class[] parameterTypes = invocation2.getParameterTypes();
             Object[] arguments = invocation2.getArguments();
@@ -75,77 +80,15 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
                 args = PojoUtils.generalize(arguments);
             }
 
-            invocation2.setMethodName(Constants.$INVOKE);
+            if (RpcUtils.isReturnTypeFuture(invocation)) {
+                invocation2.setMethodName(Constants.$INVOKE_ASYNC);
+            } else {
+                invocation2.setMethodName(Constants.$INVOKE);
+            }
             invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES);
             invocation2.setArguments(new Object[]{methodName, types, args});
-            Result result = invoker.invoke(invocation2);
-
-            if (!result.hasException()) {
-                Object value = result.getValue();
-                try {
-                    Method method = invoker.getInterface().getMethod(methodName, parameterTypes);
-                    if (ProtocolUtils.isBeanGenericSerialization(generic)) {
-                        if (value == null) {
-                            return new RpcResult(value);
-                        } else if (value instanceof JavaBeanDescriptor) {
-                            return new RpcResult(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
-                        } else {
-                            throw new RpcException(
-                                    "The type of result value is " +
-                                            value.getClass().getName() +
-                                            " other than " +
-                                            JavaBeanDescriptor.class.getName() +
-                                            ", and the result is " +
-                                            value);
-                        }
-                    } else {
-                        return new RpcResult(PojoUtils.realize(value, method.getReturnType(), method.getGenericReturnType()));
-                    }
-                } catch (NoSuchMethodException e) {
-                    throw new RpcException(e.getMessage(), e);
-                }
-            } else if (result.getException() instanceof GenericException) {
-                GenericException exception = (GenericException) result.getException();
-                try {
-                    String className = exception.getExceptionClass();
-                    Class clazz = ReflectUtils.forName(className);
-                    Throwable targetException = null;
-                    Throwable lastException = null;
-                    try {
-                        targetException = (Throwable) clazz.newInstance();
-                    } catch (Throwable e) {
-                        lastException = e;
-                        for (Constructor constructor : clazz.getConstructors()) {
-                            try {
-                                targetException = (Throwable) constructor.newInstance(new Object[constructor.getParameterTypes().length]);
-                                break;
-                            } catch (Throwable e1) {
-                                lastException = e1;
-                            }
-                        }
-                    }
-                    if (targetException != null) {
-                        try {
-                            Field field = Throwable.class.getDeclaredField("detailMessage");
-                            if (!field.isAccessible()) {
-                                field.setAccessible(true);
-                            }
-                            field.set(targetException, exception.getExceptionMessage());
-                        } catch (Throwable e) {
-                            logger.warn(e.getMessage(), e);
-                        }
-                        result = new RpcResult(targetException);
-                    } else if (lastException != null) {
-                        throw lastException;
-                    }
-                } catch (Throwable e) {
-                    throw new RpcException("Can not deserialize exception " + exception.getExceptionClass() + ", message: " + exception.getExceptionMessage(), e);
-                }
-            }
-            return result;
-        }
-
-        if (invocation.getMethodName().equals(Constants.$INVOKE)
+            return invoker.invoke(invocation2);
+        } else if ((invocation.getMethodName().equals(Constants.$INVOKE) || invocation.getMethodName().equals(Constants.$INVOKE_ASYNC))
                 && invocation.getArguments() != null
                 && invocation.getArguments().length == 3
                 && ProtocolUtils.isGeneric(generic)) {
@@ -166,20 +109,89 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
                 }
             }
 
-            ((RpcInvocation) invocation).setAttachment(
+            invocation.setAttachment(
                     Constants.GENERIC_KEY, invoker.getUrl().getParameter(Constants.GENERIC_KEY));
         }
         return invoker.invoke(invocation);
     }
 
     private void error(String generic, String expected, String actual) throws RpcException {
-        throw new RpcException(
-                "Generic serialization [" +
-                        generic +
-                        "] only support message type " +
-                        expected +
-                        " and your message type is " +
-                        actual);
+        throw new RpcException("Generic serialization [" + generic + "] only support message type " + expected + " and your message type is " + actual);
+    }
+
+    static class GenericImplListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            String generic = invoker.getUrl().getParameter(Constants.GENERIC_KEY);
+            String methodName = invocation.getMethodName();
+            Class[] parameterTypes = invocation.getParameterTypes();
+            if (ProtocolUtils.isGeneric(generic)
+                    && (!Constants.$INVOKE.equals(invocation.getMethodName()) && !Constants.$INVOKE_ASYNC.equals(invocation.getMethodName()))
+                    && invocation instanceof RpcInvocation) {
+                if (!result.hasException()) {
+                    Object value = result.getValue();
+                    try {
+                        Method method = invoker.getInterface().getMethod(methodName, parameterTypes);
+                        if (ProtocolUtils.isBeanGenericSerialization(generic)) {
+                            if (value == null) {
+                                result.setValue(value);
+                            } else if (value instanceof JavaBeanDescriptor) {
+                                result.setValue(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
+                            } else {
+                                throw new RpcException("The type of result value is " + value.getClass().getName() + " other than " + JavaBeanDescriptor.class.getName() + ", and the result is " + value);
+                            }
+                        } else {
+                            Type[] types = ReflectUtils.getReturnTypes(method);
+                            result.setValue(PojoUtils.realize(value, (Class) types[0], types[1]));
+                        }
+                    } catch (NoSuchMethodException e) {
+                        throw new RpcException(e.getMessage(), e);
+                    }
+                } else if (result.getException() instanceof GenericException) {
+                    GenericException exception = (GenericException) result.getException();
+                    try {
+                        String className = exception.getExceptionClass();
+                        Class clazz = ReflectUtils.forName(className);
+                        Throwable targetException = null;
+                        Throwable lastException = null;
+                        try {
+                            targetException = (Throwable) clazz.newInstance();
+                        } catch (Throwable e) {
+                            lastException = e;
+                            for (Constructor constructor : clazz.getConstructors()) {
+                                try {
+                                    targetException = (Throwable) constructor.newInstance(new Object[constructor.getParameterTypes().length]);
+                                    break;
+                                } catch (Throwable e1) {
+                                    lastException = e1;
+                                }
+                            }
+                        }
+                        if (targetException != null) {
+                            try {
+                                Field field = Throwable.class.getDeclaredField("detailMessage");
+                                if (!field.isAccessible()) {
+                                    field.setAccessible(true);
+                                }
+                                field.set(targetException, exception.getExceptionMessage());
+                            } catch (Throwable e) {
+                                logger.warn(e.getMessage(), e);
+                            }
+                            result.setException(targetException);
+                        } else if (lastException != null) {
+                            throw lastException;
+                        }
+                    } catch (Throwable e) {
+                        throw new RpcException("Can not deserialize exception " + exception.getExceptionClass() + ", message: " + exception.getExceptionMessage(), e);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
     }
 
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java
index c00689fc1c82..b6335823d8ef 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java
@@ -20,12 +20,11 @@
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcInvocation;
 
 import java.util.Arrays;
 
@@ -33,42 +32,40 @@
  * Log any invocation timeout, but don't stop server from running
  */
 @Activate(group = Constants.PROVIDER)
-public class TimeoutFilter implements Filter {
+public class TimeoutFilter extends ListenableFilter {
 
     private static final Logger logger = LoggerFactory.getLogger(TimeoutFilter.class);
 
     private static final String TIMEOUT_FILTER_START_TIME = "timeout_filter_start_time";
 
+    public TimeoutFilter() {
+        super.listener = new TimeoutListener();
+    }
+
     @Override
     public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
-        if (invocation.getAttachments() != null) {
-            long start = System.currentTimeMillis();
-            invocation.getAttachments().put(TIMEOUT_FILTER_START_TIME, String.valueOf(start));
-        } else {
-            if (invocation instanceof RpcInvocation) {
-                RpcInvocation invc = (RpcInvocation) invocation;
-                long start = System.currentTimeMillis();
-                invc.setAttachment(TIMEOUT_FILTER_START_TIME, String.valueOf(start));
-            }
-        }
+        invocation.setAttachment(TIMEOUT_FILTER_START_TIME, String.valueOf(System.currentTimeMillis()));
         return invoker.invoke(invocation);
     }
 
-    @Override
-    public Result onResponse(Result result, Invoker invoker, Invocation invocation) {
-        String startAttach = invocation.getAttachment(TIMEOUT_FILTER_START_TIME);
-        if (startAttach != null) {
-            long elapsed = System.currentTimeMillis() - Long.valueOf(startAttach);
-            if (invoker.getUrl() != null
-                    && elapsed > invoker.getUrl().getMethodParameter(invocation.getMethodName(),
-                    "timeout", Integer.MAX_VALUE)) {
-                if (logger.isWarnEnabled()) {
-                    logger.warn("invoke time out. method: " + invocation.getMethodName()
-                            + " arguments: " + Arrays.toString(invocation.getArguments()) + " , url is "
-                            + invoker.getUrl() + ", invoke elapsed " + elapsed + " ms.");
+    static class TimeoutListener implements Listener {
+
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            String startAttach = invocation.getAttachment(TIMEOUT_FILTER_START_TIME);
+            if (startAttach != null) {
+                long elapsed = System.currentTimeMillis() - Long.valueOf(startAttach);
+                if (invoker.getUrl() != null && elapsed > invoker.getUrl().getMethodParameter(invocation.getMethodName(), "timeout", Integer.MAX_VALUE)) {
+                    if (logger.isWarnEnabled()) {
+                        logger.warn("invoke time out. method: " + invocation.getMethodName() + " arguments: " + Arrays.toString(invocation.getArguments()) + " , url is " + invoker.getUrl() + ", invoke elapsed " + elapsed + " ms.");
+                    }
                 }
             }
         }
-        return result;
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java
index 3df1f1d741e8..58cb4105f864 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java
@@ -16,7 +16,6 @@
  */
 package org.apache.dubbo.rpc.protocol;
 
-import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.Version;
 import org.apache.dubbo.common.logger.Logger;
@@ -24,13 +23,13 @@
 import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.NetUtils;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.lang.reflect.InvocationTargetException;
@@ -148,9 +147,8 @@ public Result invoke(Invocation inv) throws RpcException {
              */
             invocation.addAttachments(contextAttachments);
         }
-        if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)) {
-            invocation.setAttachment(Constants.ASYNC_KEY, Boolean.TRUE.toString());
-        }
+
+        invocation.setInvokeMode(RpcUtils.getInvokeMode(url, invocation));
         RpcUtils.attachInvocationIdIfAsync(getUrl(), invocation);
 
         try {
@@ -158,21 +156,21 @@ public Result invoke(Invocation inv) throws RpcException {
         } catch (InvocationTargetException e) { // biz exception
             Throwable te = e.getTargetException();
             if (te == null) {
-                return new RpcResult(e);
+                return AsyncRpcResult.newDefaultAsyncResult(null, e, invocation);
             } else {
                 if (te instanceof RpcException) {
                     ((RpcException) te).setCode(RpcException.BIZ_EXCEPTION);
                 }
-                return new RpcResult(te);
+                return AsyncRpcResult.newDefaultAsyncResult(null, te, invocation);
             }
         } catch (RpcException e) {
             if (e.isBiz()) {
-                return new RpcResult(e);
+                return AsyncRpcResult.newDefaultAsyncResult(null, e, invocation);
             } else {
                 throw e;
             }
         } catch (Throwable e) {
-            return new RpcResult(e);
+            return AsyncRpcResult.newDefaultAsyncResult(null, e, invocation);
         }
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
index 814e9182280b..a2a6ebb135fd 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java
@@ -24,6 +24,7 @@
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Protocol;
+import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
 import java.util.ArrayList;
@@ -82,4 +83,11 @@ public void destroy() {
             }
         }
     }
+
+    @Override
+    public  Invoker refer(Class type, URL url) throws RpcException {
+        return new AsyncToSyncInvoker<>(doRefer(type, url));
+    }
+
+    protected abstract  Invoker doRefer(Class type, URL url) throws RpcException;
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
index a77a5bdc5f38..e03d3800984a 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
@@ -92,13 +92,14 @@ public void unexport() {
     }
 
     @Override
-    public  Invoker refer(final Class type, final URL url) throws RpcException {
-        final Invoker target = proxyFactory.getInvoker(doRefer(type, url), type, url);
+    public  Invoker doRefer(final Class type, final URL url) throws RpcException {
+        final Invoker target = proxyFactory.getInvoker(getFrameworkProxy(type, url), type, url);
         Invoker invoker = new AbstractInvoker(type, url) {
             @Override
             protected Result doInvoke(Invocation invocation) throws Throwable {
                 try {
                     Result result = target.invoke(invocation);
+                    // FIXME result is an AsyncRpcResult instance.
                     Throwable e = result.getException();
                     if (e != null) {
                         for (Class rpcException : rpcExceptions) {
@@ -143,6 +144,6 @@ protected int getErrorCode(Throwable e) {
 
     protected abstract  Runnable doExport(T impl, Class type, URL url) throws RpcException;
 
-    protected abstract  T doRefer(Class type, URL url) throws RpcException;
+    protected abstract  T getFrameworkProxy(Class type, URL url) throws RpcException;
 
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AsyncToSyncInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AsyncToSyncInvoker.java
new file mode 100644
index 000000000000..5c06b4e4d1d5
--- /dev/null
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AsyncToSyncInvoker.java
@@ -0,0 +1,89 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.dubbo.rpc.protocol;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.remoting.RemotingException;
+import org.apache.dubbo.remoting.TimeoutException;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.InvokeMode;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
+
+import java.util.concurrent.ExecutionException;
+
+/**
+ * This class will work as a wrapper wrapping outside of each protocol invoker.
+ * @param 
+ */
+public class AsyncToSyncInvoker implements Invoker {
+
+    private Invoker invoker;
+
+    public AsyncToSyncInvoker(Invoker invoker) {
+        this.invoker = invoker;
+    }
+
+    @Override
+    public Class getInterface() {
+        return invoker.getInterface();
+    }
+
+    @Override
+    public Result invoke(Invocation invocation) throws RpcException {
+        Result asyncResult = invoker.invoke(invocation);
+
+        try {
+            if (InvokeMode.SYNC == ((RpcInvocation)invocation).getInvokeMode()) {
+                asyncResult.get();
+            }
+        } catch (InterruptedException e) {
+            throw new RpcException("Interrupted unexpectedly while waiting for remoting result to return!  method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
+        } catch (ExecutionException e) {
+            Throwable t = e.getCause();
+            if (t instanceof TimeoutException) {
+                throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
+            } else if (t instanceof RemotingException) {
+                throw new RpcException(RpcException.NETWORK_EXCEPTION, "Failed to invoke remote method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
+            }
+        } catch (Throwable e) {
+            throw new RpcException(e.getMessage(), e);
+        }
+        return asyncResult;
+    }
+
+    @Override
+    public URL getUrl() {
+        return invoker.getUrl();
+    }
+
+    @Override
+    public boolean isAvailable() {
+        return invoker.isAvailable();
+    }
+
+    @Override
+    public void destroy() {
+        invoker.destroy();
+    }
+
+    public Invoker getInvoker() {
+        return invoker;
+    }
+}
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java
index c5ed5943cd0f..2106a4e0da8e 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java
@@ -19,11 +19,11 @@
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
-import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Protocol;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
@@ -70,14 +70,29 @@ public boolean isAvailable() {
 
                     @Override
                     public Result invoke(Invocation invocation) throws RpcException {
-                        Result result = filter.invoke(next, invocation);
-                        if (result instanceof AsyncRpcResult) {
-                            AsyncRpcResult asyncResult = (AsyncRpcResult) result;
-                            asyncResult.thenApplyWithContext(r -> filter.onResponse(r, invoker, invocation));
-                            return asyncResult;
-                        } else {
-                            return filter.onResponse(result, invoker, invocation);
+                        Result asyncResult;
+                        try {
+                            asyncResult = filter.invoke(next, invocation);
+                        } catch (Exception e) {
+                            // onError callback
+                            if (filter instanceof ListenableFilter) {
+                                Filter.Listener listener = ((ListenableFilter) filter).listener();
+                                if (listener != null) {
+                                    listener.onError(e, invoker, invocation);
+                                }
+                            }
+                            throw e;
                         }
+                        return asyncResult.thenApplyWithContext(r -> {
+                            // onResponse callback
+                            if (filter instanceof ListenableFilter) {
+                                Filter.Listener listener = ((ListenableFilter) filter).listener();
+                                if (listener != null) {
+                                    listener.onResponse(r, invoker, invocation);
+                                }
+                            }
+                            return r;
+                        });
                     }
 
                     @Override
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java
index 6a562d6f6fda..aa813e1d1a5e 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java
@@ -19,6 +19,7 @@
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.AsyncContextImpl;
 import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
@@ -26,11 +27,11 @@
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.lang.reflect.InvocationTargetException;
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
 
 /**
  * InvokerWrapper
@@ -78,30 +79,47 @@ public boolean isAvailable() {
     public void destroy() {
     }
 
-    // TODO Unified to AsyncResult?
     @Override
     public Result invoke(Invocation invocation) throws RpcException {
-        RpcContext rpcContext = RpcContext.getContext();
         try {
-            Object obj = doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
-            if (RpcUtils.isReturnTypeFuture(invocation)) {
-                return new AsyncRpcResult((CompletableFuture) obj);
-            } else if (rpcContext.isAsyncStarted()) { // ignore obj in case of RpcContext.startAsync()? always rely on user to write back.
-                return new AsyncRpcResult(((AsyncContextImpl)(rpcContext.getAsyncContext())).getInternalFuture());
-            } else {
-                return new RpcResult(obj);
-            }
+            Object value = doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments());
+            CompletableFuture future = wrapWithFuture(value, invocation);
+            CompletableFuture appResponseFuture = future.handle((obj, t) -> {
+                AppResponse result = new AppResponse();
+                if (t != null) {
+                    if (t instanceof CompletionException) {
+                        result.setException(t.getCause());
+                    } else {
+                        result.setException(t);
+                    }
+                } else {
+                    result.setValue(obj);
+                }
+                return result;
+            });
+            return new AsyncRpcResult(appResponseFuture, invocation);
         } catch (InvocationTargetException e) {
-            // TODO async throw exception before async thread write back, should stop asyncContext
-            if (rpcContext.isAsyncStarted() && !rpcContext.stopAsync()) {
+            if (RpcContext.getContext().isAsyncStarted() && !RpcContext.getContext().stopAsync()) {
                 logger.error("Provider async started, but got an exception from the original method, cannot write the exception back to consumer because an async result may have returned the new thread.", e);
             }
-            return new RpcResult(e.getTargetException());
+            return AsyncRpcResult.newDefaultAsyncResult(null, e.getTargetException(), invocation);
         } catch (Throwable e) {
             throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to " + getUrl() + ", cause: " + e.getMessage(), e);
         }
     }
 
+    private CompletableFuture wrapWithFuture (Object value, Invocation invocation) {
+        if (RpcContext.getContext().isAsyncStarted()) {
+            return ((AsyncContextImpl)(RpcContext.getContext().getAsyncContext())).getInternalFuture();
+        } else if (RpcUtils.isReturnTypeFuture(invocation)) {
+            if (value == null) {
+                return CompletableFuture.completedFuture(null);
+            }
+            return (CompletableFuture) value;
+        }
+        return CompletableFuture.completedFuture(value);
+    }
+
     protected abstract Object doInvoke(T proxy, String methodName, Class[] parameterTypes, Object[] arguments) throws Throwable;
 
     @Override
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
index 3cdb65c742f1..1d047cdccf42 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java
@@ -16,12 +16,10 @@
  */
 package org.apache.dubbo.rpc.proxy;
 
-import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
@@ -54,16 +52,6 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl
             return invoker.equals(args[0]);
         }
 
-        return invoker.invoke(createInvocation(method, args)).recreate();
+        return invoker.invoke(new RpcInvocation(method, args)).recreate();
     }
-
-    private RpcInvocation createInvocation(Method method, Object[] args) {
-        RpcInvocation invocation = new RpcInvocation(method, args);
-        if (RpcUtils.hasFutureReturnType(method)) {
-            invocation.setAttachment(Constants.FUTURE_RETURNTYPE_KEY, "true");
-            invocation.setAttachment(Constants.ASYNC_KEY, "true");
-        }
-        return invocation;
-    }
-
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/service/GenericService.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/service/GenericService.java
index 07517d474a41..d93fa14930af 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/service/GenericService.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/service/GenericService.java
@@ -16,6 +16,8 @@
  */
 package org.apache.dubbo.rpc.service;
 
+import java.util.concurrent.CompletableFuture;
+
 /**
  * Generic service interface
  *
@@ -35,4 +37,12 @@ public interface GenericService {
      */
     Object $invoke(String method, String[] parameterTypes, Object[] args) throws GenericException;
 
+    default CompletableFuture $invokeAsync(String method, String[] parameterTypes, Object[] args) throws GenericException {
+        Object object = $invoke(method, parameterTypes, args);
+        if (object instanceof CompletableFuture) {
+            return (CompletableFuture) object;
+        }
+        return CompletableFuture.completedFuture(object);
+    }
+
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java
index 923c7cb0fd15..a7f973a832a5 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java
@@ -19,18 +19,18 @@
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.common.utils.ConfigUtils;
 import org.apache.dubbo.common.utils.PojoUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
-import org.apache.dubbo.common.utils.ArrayUtils;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.ProxyFactory;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 
 import com.alibaba.fastjson.JSON;
 
@@ -106,7 +106,7 @@ public Result invoke(Invocation invocation) throws RpcException {
             try {
                 Type[] returnTypes = RpcUtils.getReturnTypes(invocation);
                 Object value = parseMockValue(mock, returnTypes);
-                return new RpcResult(value);
+                return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
             } catch (Exception ew) {
                 throw new RpcException("mock return invoke error. method :" + invocation.getMethodName()
                         + ", mock:" + mock + ", url: " + url, ew);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java
index 9237ab955c07..ecf7a4524f51 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java
@@ -38,7 +38,7 @@ public  Exporter export(Invoker invoker) throws RpcException {
     }
 
     @Override
-    public  Invoker refer(Class type, URL url) throws RpcException {
+    public  Invoker doRefer(Class type, URL url) throws RpcException {
         return new MockInvoker<>(url, type);
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
index a5ae76133cfb..ca55dfbe8ca2 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java
@@ -23,15 +23,14 @@
 import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.InvokeMode;
 import org.apache.dubbo.rpc.RpcInvocation;
 
 import java.lang.reflect.Method;
-import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -65,7 +64,6 @@ public static Class getReturnType(Invocation invocation) {
         return null;
     }
 
-    // TODO why not get return type when initialize Invocation?
     public static Type[] getReturnTypes(Invocation invocation) {
         try {
             if (invocation != null && invocation.getInvoker() != null
@@ -80,24 +78,7 @@ public static Type[] getReturnTypes(Invocation invocation) {
                     if (method.getReturnType() == void.class) {
                         return null;
                     }
-                    Class returnType = method.getReturnType();
-                    Type genericReturnType = method.getGenericReturnType();
-                    if (Future.class.isAssignableFrom(returnType)) {
-                        if (genericReturnType instanceof ParameterizedType) {
-                            Type actualArgType = ((ParameterizedType) genericReturnType).getActualTypeArguments()[0];
-                            if (actualArgType instanceof ParameterizedType) {
-                                returnType = (Class) ((ParameterizedType) actualArgType).getRawType();
-                                genericReturnType = actualArgType;
-                            } else {
-                                returnType = (Class) actualArgType;
-                                genericReturnType = returnType;
-                            }
-                        } else {
-                            returnType = null;
-                            genericReturnType = null;
-                        }
-                    }
-                    return new Type[]{returnType, genericReturnType};
+                    return ReflectUtils.getReturnTypes(method);
                 }
             }
         } catch (Throwable t) {
@@ -184,11 +165,22 @@ public static boolean isAsync(URL url, Invocation inv) {
     }
 
     public static boolean isReturnTypeFuture(Invocation inv) {
-        return Boolean.TRUE.toString().equals(inv.getAttachment(Constants.FUTURE_RETURNTYPE_KEY));
+        Class clazz = getReturnType(inv);
+        return (clazz != null && CompletableFuture.class.isAssignableFrom(clazz)) || isGenericAsync(inv);
+    }
+
+    public static InvokeMode getInvokeMode(URL url, Invocation inv) {
+        if (isReturnTypeFuture(inv)) {
+            return InvokeMode.FUTURE;
+        } else if (isAsync(url, inv)) {
+            return InvokeMode.ASYNC;
+        } else {
+            return InvokeMode.SYNC;
+        }
     }
 
-    public static boolean hasFutureReturnType(Method method) {
-        return CompletableFuture.class.isAssignableFrom(method.getReturnType());
+    public static boolean isGenericAsync(Invocation inv) {
+        return Constants.$INVOKE_ASYNC.equals(inv.getMethodName());
     }
 
     public static boolean isOneway(URL url, Invocation inv) {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcResultTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/AppResponseTest.java
similarity index 100%
rename from dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/RpcResultTest.java
rename to dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/AppResponseTest.java
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java
index 6d085f70617f..9c749c983c51 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ActiveLimitFilterTest.java
@@ -17,9 +17,9 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcStatus;
 import org.apache.dubbo.rpc.support.BlockMyInvoker;
@@ -35,13 +35,14 @@
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.fail;
 
 /**
  * ActiveLimitFilterTest.java
  */
 public class ActiveLimitFilterTest {
 
-    Filter activeLimitFilter = new ActiveLimitFilter();
+    ActiveLimitFilter activeLimitFilter = new ActiveLimitFilter();
 
     @Test
     public void testInvokeNoActives() {
@@ -97,7 +98,7 @@ public void run() {
     }
 
     @Test
-    public void testInvokeTimeOut() {
+    public void testInvokeTimeOut() throws Exception {
         int totalThread = 100;
         int maxActives = 10;
         long timeout = 1;
@@ -120,9 +121,14 @@ public void run() {
                             e.printStackTrace();
                         }
                         try {
-                            activeLimitFilter.invoke(invoker, invocation);
+                            Result asyncResult = activeLimitFilter.invoke(invoker, invocation);
+                            Result result = asyncResult.get();
+                            activeLimitFilter.listener().onResponse(result, invoker, invocation);
                         } catch (RpcException expected) {
                             count.incrementAndGet();
+//                            activeLimitFilter.listener().onError(expected, invoker, invocation);
+                        } catch (Exception e) {
+                            fail();
                         }
                     } finally {
                         latchBlocking.countDown();
@@ -142,7 +148,7 @@ public void run() {
     }
 
     @Test
-    public void testInvokeNotTimeOut() {
+    public void testInvokeNotTimeOut() throws Exception {
         int totalThread = 100;
         int maxActives = 10;
         long timeout = 1000;
@@ -163,9 +169,14 @@ public void run() {
                             e.printStackTrace();
                         }
                         try {
-                            activeLimitFilter.invoke(invoker, invocation);
+                            Result asyncResult = activeLimitFilter.invoke(invoker, invocation);
+                            Result result = asyncResult.get();
+                            activeLimitFilter.listener().onResponse(result, invoker, invocation);
                         } catch (RpcException expected) {
                             count.incrementAndGet();
+                            activeLimitFilter.listener().onError(expected, invoker, invocation);
+                        } catch (Exception e) {
+                            fail();
                         }
                     } finally {
                         latchBlocking.countDown();
@@ -208,6 +219,7 @@ public void testInvokeRuntimeExceptionWithActiveCountMatch() {
         try {
             activeLimitFilter.invoke(invoker, invocation);
         } catch (RuntimeException ex) {
+            activeLimitFilter.listener().onError(ex, invoker, invocation);
             int afterExceptionActiveCount = count.getActive();
             assertEquals(beforeExceptionActiveCount, afterExceptionActiveCount, "After exception active count should be same");
         }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java
index b91c92d1640d..e16dfbd8f610 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java
@@ -17,13 +17,14 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.Filter;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.DemoService;
 import org.apache.dubbo.rpc.support.Type;
+
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -37,7 +38,7 @@
  * CompatibleFilterTest.java
  */
 public class CompatibleFilterFilterTest {
-    private Filter compatibleFilter = new CompatibleFilter();
+    private CompatibleFilter compatibleFilter = new CompatibleFilter();
     private Invocation invocation;
     private Invoker invoker;
 
@@ -56,7 +57,7 @@ public void testInvokerGeneric() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
@@ -76,7 +77,7 @@ public void testResulthasException() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setException(new RuntimeException());
         result.setValue("High");
         given(invoker.invoke(invocation)).willReturn(result);
@@ -88,7 +89,7 @@ public void testResulthasException() {
     }
 
     @Test
-    public void testInvokerJsonPojoSerialization() {
+    public void testInvokerJsonPojoSerialization() throws Exception {
         invocation = mock(Invocation.class);
         given(invocation.getMethodName()).willReturn("enumlength");
         given(invocation.getParameterTypes()).willReturn(new Class[]{Type[].class});
@@ -97,18 +98,20 @@ public void testInvokerJsonPojoSerialization() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
-        given(invoker.invoke(invocation)).willReturn(result);
+        given(invoker.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(result, invocation));
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1&serialization=json");
         given(invoker.getUrl()).willReturn(url);
 
-        Result filterResult = compatibleFilter.invoke(invoker, invocation);
-        assertEquals(Type.High, filterResult.getValue());
+        Result asyncResult = compatibleFilter.invoke(invoker, invocation);
+        Result rpcResult = asyncResult.get();
+        compatibleFilter.listener().onResponse(rpcResult, invoker, invocation);
+        assertEquals(Type.High, rpcResult.getValue());
     }
 
     @Test
-    public void testInvokerNonJsonEnumSerialization() {
+    public void testInvokerNonJsonEnumSerialization() throws Exception {
         invocation = mock(Invocation.class);
         given(invocation.getMethodName()).willReturn("enumlength");
         given(invocation.getParameterTypes()).willReturn(new Class[]{Type[].class});
@@ -117,14 +120,16 @@ public void testInvokerNonJsonEnumSerialization() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
-        given(invoker.invoke(invocation)).willReturn(result);
+        given(invoker.invoke(invocation)).willReturn(AsyncRpcResult.newDefaultAsyncResult(result, invocation));
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
         given(invoker.getUrl()).willReturn(url);
 
-        Result filterResult = compatibleFilter.invoke(invoker, invocation);
-        assertEquals(Type.High, filterResult.getValue());
+        Result asyncResult = compatibleFilter.invoke(invoker, invocation);
+        Result rpcResult = asyncResult.get();
+        compatibleFilter.listener().onResponse(rpcResult, invoker, invocation);
+        assertEquals(Type.High, rpcResult.getValue());
     }
 
     @Test
@@ -137,7 +142,7 @@ public void testInvokerNonJsonNonPojoSerialization() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue(new String[]{"High"});
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
@@ -157,7 +162,7 @@ public void testInvokerNonJsonPojoSerialization() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("hello");
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ConsumerContextFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ConsumerContextFilterTest.java
index a906af47be23..93635528338a 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ConsumerContextFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ConsumerContextFilterTest.java
@@ -21,6 +21,7 @@
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.support.DemoService;
 import org.apache.dubbo.rpc.support.MockInvocation;
@@ -41,11 +42,13 @@ public void testSetContext() {
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
         Invoker invoker = new MyInvoker(url);
         Invocation invocation = new MockInvocation();
-        consumerContextFilter.invoke(invoker, invocation);
-        assertEquals(invoker, RpcContext.getContext().getInvoker());
-        assertEquals(invocation, RpcContext.getContext().getInvocation());
-        assertEquals(NetUtils.getLocalHost() + ":0", RpcContext.getContext().getLocalAddressString());
-        assertEquals("test:11", RpcContext.getContext().getRemoteAddressString());
-
+        Result asyncResult = consumerContextFilter.invoke(invoker, invocation);
+        asyncResult.thenApplyWithContext(result -> {
+            assertEquals(invoker, RpcContext.getContext().getInvoker());
+            assertEquals(invocation, RpcContext.getContext().getInvocation());
+            assertEquals(NetUtils.getLocalHost() + ":0", RpcContext.getContext().getLocalAddressString());
+            assertEquals("test:11", RpcContext.getContext().getRemoteAddressString());
+            return result;
+        });
     }
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ContextFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ContextFilterTest.java
index c753c7e0e2e7..506c10db5d57 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ContextFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ContextFilterTest.java
@@ -17,12 +17,12 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.DemoService;
 import org.apache.dubbo.rpc.support.MockInvocation;
 import org.apache.dubbo.rpc.support.MyInvoker;
@@ -55,7 +55,7 @@ public void testSetContext() {
         invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/EchoFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/EchoFilterTest.java
index 02f367b8a8e7..3befdc77df99 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/EchoFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/EchoFilterTest.java
@@ -17,11 +17,11 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.DemoService;
 
 import org.junit.jupiter.api.Test;
@@ -46,7 +46,7 @@ public void testEcho() {
         Invoker invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
@@ -68,7 +68,7 @@ public void testNonEcho() {
         Invoker invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java
index f40f8776e454..964e06ecb153 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java
@@ -17,13 +17,13 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.logger.Logger;
-import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.DemoService;
 import org.apache.dubbo.rpc.support.LocalException;
 
@@ -33,6 +33,8 @@
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
+import java.util.concurrent.CompletableFuture;
+
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.BDDMockito.given;
@@ -51,18 +53,20 @@ public void testRpcException() {
         RpcContext.getContext().setRemoteAddress("127.0.0.1", 1234);
         RpcException exception = new RpcException("TestRpcException");
 
-        ExceptionFilter exceptionFilter = new ExceptionFilter(logger);
+        ExceptionFilter exceptionFilter = new ExceptionFilter();
         RpcInvocation invocation = new RpcInvocation("sayHello", new Class[]{String.class}, new Object[]{"world"});
         Invoker invoker = mock(Invoker.class);
         given(invoker.getInterface()).willReturn(DemoService.class);
         given(invoker.invoke(eq(invocation))).willThrow(exception);
 
-
         try {
             exceptionFilter.invoke(invoker, invocation);
         } catch (RpcException e) {
             assertEquals("TestRpcException", e.getMessage());
+            ((ExceptionFilter.ExceptionListener) exceptionFilter.listener()).setLogger(logger);
+            exceptionFilter.listener().onError(e, invoker, invocation);
         }
+
         Mockito.verify(logger).error(eq("Got unchecked and undeclared exception which called by 127.0.0.1. service: "
                 + DemoService.class.getName() + ", method: sayHello, exception: "
                 + RpcException.class.getName() + ": TestRpcException"), eq(exception));
@@ -76,7 +80,7 @@ public void testJavaException() {
         ExceptionFilter exceptionFilter = new ExceptionFilter();
         RpcInvocation invocation = new RpcInvocation("sayHello", new Class[]{String.class}, new Object[]{"world"});
 
-        RpcResult rpcResult = new RpcResult();
+        AppResponse rpcResult = new AppResponse();
         rpcResult.setException(new IllegalArgumentException("java"));
 
         Invoker invoker = mock(Invoker.class);
@@ -96,7 +100,7 @@ public void testRuntimeException() {
         ExceptionFilter exceptionFilter = new ExceptionFilter();
         RpcInvocation invocation = new RpcInvocation("sayHello", new Class[]{String.class}, new Object[]{"world"});
 
-        RpcResult rpcResult = new RpcResult();
+        AppResponse rpcResult = new AppResponse();
         rpcResult.setException(new LocalException("localException"));
 
         Invoker invoker = mock(Invoker.class);
@@ -111,27 +115,28 @@ public void testRuntimeException() {
 
     @SuppressWarnings("unchecked")
     @Test
-    public void testConvertToRunTimeException() {
+    public void testConvertToRunTimeException() throws Exception {
 
         ExceptionFilter exceptionFilter = new ExceptionFilter();
         RpcInvocation invocation = new RpcInvocation("sayHello", new Class[]{String.class}, new Object[]{"world"});
 
-        RpcResult rpcResult = new RpcResult();
-        rpcResult.setException(new HessianException("hessian"));
+        AppResponse mockRpcResult = new AppResponse();
+        mockRpcResult.setException(new HessianException("hessian"));
+        Result mockAsyncResult = new AsyncRpcResult(CompletableFuture.completedFuture(mockRpcResult), invocation);
+
 
         Invoker invoker = mock(Invoker.class);
-        when(invoker.invoke(invocation)).thenReturn(rpcResult);
+        when(invoker.invoke(invocation)).thenReturn(mockAsyncResult);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
-        Result newResult = exceptionFilter.invoke(invoker, invocation);
-
-        newResult = exceptionFilter.onResponse(newResult, invoker, invocation);
+        Result asyncResult = exceptionFilter.invoke(invoker, invocation);
 
-        Assertions.assertFalse(newResult.getException() instanceof HessianException);
+        Result rpcResult = asyncResult.get();
+        exceptionFilter.listener().onResponse(rpcResult, invoker, invocation);
 
-        Assertions.assertEquals(newResult.getException().getClass(), RuntimeException.class);
-        Assertions.assertEquals(newResult.getException().getMessage(), StringUtils.toString(rpcResult.getException()));
+        Assertions.assertFalse(rpcResult.getException() instanceof HessianException);
 
+        Assertions.assertEquals(rpcResult.getException().getClass(), RuntimeException.class);
     }
 
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilterTest.java
index 2fab7894e32f..4cbc280275d0 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilterTest.java
@@ -17,11 +17,11 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.RpcStatus;
 import org.apache.dubbo.rpc.support.BlockMyInvoker;
 
@@ -43,7 +43,7 @@ public class ExecuteLimitFilterTest {
     @Test
     public void testNoExecuteLimitInvoke() throws Exception {
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult("result"));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
         when(invoker.getUrl()).thenReturn(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1"));
 
         Invocation invocation = Mockito.mock(Invocation.class);
@@ -56,7 +56,7 @@ public void testNoExecuteLimitInvoke() throws Exception {
     @Test
     public void testExecuteLimitInvoke() throws Exception {
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult("result"));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
         when(invoker.getUrl()).thenReturn(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&executes=10"));
 
         Invocation invocation = Mockito.mock(Invocation.class);
@@ -82,6 +82,7 @@ public void testExecuteLimitInvokeWitException() throws Exception {
             executeLimitFilter.invoke(invoker, invocation);
         } catch (Exception e) {
             Assertions.assertTrue(e instanceof RpcException);
+            executeLimitFilter.listener().onError(e, invoker, invocation);
         }
         Assertions.assertEquals(1, RpcStatus.getStatus(url, invocation.getMethodName()).getFailed());
     }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java
index bd680e7502ee..f2358ddaeca1 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java
@@ -18,7 +18,13 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.rpc.*;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
+import org.apache.dubbo.rpc.Invocation;
+import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
+import org.apache.dubbo.rpc.RpcException;
+import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.DemoService;
 import org.apache.dubbo.rpc.support.Person;
@@ -52,14 +58,16 @@ public void testInvokeWithDefault() throws Exception {
         URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
                 "accesslog=true&group=dubbo&version=1.1");
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult(new Person("person", 10)));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(AsyncRpcResult.newDefaultAsyncResult(new Person("person", 10), invocation));
         when(invoker.getUrl()).thenReturn(url);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
-        Result result = genericFilter.invoke(invoker, invocation);
+        Result asyncResult = genericFilter.invoke(invoker, invocation);
 
-        Assertions.assertEquals(HashMap.class, result.getValue().getClass());
-        Assertions.assertEquals(10, ((HashMap) result.getValue()).get("age"));
+        Result rpcResult = asyncResult.get();
+        genericFilter.listener().onResponse(rpcResult, invoker, invocation);
+        Assertions.assertEquals(HashMap.class, rpcResult.getValue().getClass());
+        Assertions.assertEquals(10, ((HashMap) rpcResult.getValue()).get("age"));
 
     }
 
@@ -79,7 +87,7 @@ public void testInvokeWithJavaException() throws Exception {
             URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
                     "accesslog=true&group=dubbo&version=1.1");
             Invoker invoker = Mockito.mock(Invoker.class);
-            when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult(new Person("person", 10)));
+            when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse(new Person("person", 10)));
             when(invoker.getUrl()).thenReturn(url);
             when(invoker.getInterface()).thenReturn(DemoService.class);
 
@@ -102,7 +110,7 @@ public void testInvokeWithJavaException() throws Exception {
         URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
                 "accesslog=true&group=dubbo&version=1.1");
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult(new Person("person", 10)));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse(new Person("person", 10)));
         when(invoker.getUrl()).thenReturn(url);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
@@ -126,7 +134,7 @@ public void testInvokeWithMethodArgumentSizeIsNot3() {
         URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
                 "accesslog=true&group=dubbo&version=1.1");
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult(new Person("person", 10)));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse(new Person("person", 10)));
         when(invoker.getUrl()).thenReturn(url);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java
index 43930ef66059..469632b9ec37 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java
@@ -18,11 +18,12 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.service.GenericException;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.DemoService;
@@ -35,6 +36,7 @@
 import java.lang.reflect.Method;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.concurrent.CompletableFuture;
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.when;
@@ -58,11 +60,14 @@ public void testInvoke() throws Exception {
         person.put("name", "dubbo");
         person.put("age", 10);
 
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult(person));
+        AppResponse mockRpcResult = new AppResponse(person);
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AsyncRpcResult(CompletableFuture.completedFuture(mockRpcResult), invocation));
         when(invoker.getUrl()).thenReturn(url);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
-        Result result = genericImplFilter.invoke(invoker, invocation);
+        Result asyncResult = genericImplFilter.invoke(invoker, invocation);
+        Result result = asyncResult.get();
+        genericImplFilter.listener().onResponse(result, invoker, invocation);
 
         Assertions.assertEquals(Person.class, result.getValue().getClass());
         Assertions.assertEquals(10, ((Person) result.getValue()).getAge());
@@ -78,12 +83,14 @@ public void testInvokeWithException() throws Exception {
                 "accesslog=true&group=dubbo&version=1.1&generic=true");
         Invoker invoker = Mockito.mock(Invoker.class);
 
-        when(invoker.invoke(any(Invocation.class))).thenReturn(
-                new RpcResult(new GenericException(new RuntimeException("failed"))));
+        AppResponse mockRpcResult = new AppResponse(new GenericException(new RuntimeException("failed")));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AsyncRpcResult(CompletableFuture.completedFuture(mockRpcResult), invocation));
         when(invoker.getUrl()).thenReturn(url);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
-        Result result = genericImplFilter.invoke(invoker, invocation);
+        Result asyncResult = genericImplFilter.invoke(invoker, invocation);
+        Result result = asyncResult.get();
+        genericImplFilter.listener().onResponse(result, invoker, invocation);
         Assertions.assertEquals(RuntimeException.class, result.getException().getClass());
 
     }
@@ -103,7 +110,7 @@ public void testInvokeWithException() throws Exception {
         URL url = URL.valueOf("test://test:11/org.apache.dubbo.rpc.support.DemoService?" +
                 "accesslog=true&group=dubbo&version=1.1&generic=true");
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult(new Person("person", 10)));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse(new Person("person", 10)));
         when(invoker.getUrl()).thenReturn(url);
 
         genericImplFilter.invoke(invoker, invocation);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java
index f99a0f35480b..be8536533352 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TimeoutFilterTest.java
@@ -17,10 +17,10 @@
 package org.apache.dubbo.rpc.filter;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.BlockMyInvoker;
 
 import org.junit.jupiter.api.Assertions;
@@ -39,7 +39,7 @@ public void testInvokeWithoutTimeout() throws Exception {
         int timeout = 3000;
 
         Invoker invoker = Mockito.mock(Invoker.class);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult("result"));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
         when(invoker.getUrl()).thenReturn(URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&timeout=" + timeout));
 
         Invocation invocation = Mockito.mock(Invocation.class);
@@ -60,7 +60,7 @@ public void testInvokeWithTimeout() throws Exception {
         when(invocation.getMethodName()).thenReturn("testInvokeWithTimeout");
 
         Result result = timeoutFilter.invoke(invoker, invocation);
-        Assertions.assertEquals("alibaba", result.getValue());
+        Assertions.assertEquals("Dubbo", result.getValue());
 
     }
 }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java
index fea5c300e072..5b86459624a1 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/TokenFilterTest.java
@@ -18,11 +18,11 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
@@ -45,7 +45,7 @@ public void testInvokeWithToken() throws Exception {
         Invoker invoker = Mockito.mock(Invoker.class);
         URL url = URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&token=" + token);
         when(invoker.getUrl()).thenReturn(url);
-        when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult("result"));
+        when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
 
         Map attachments = new HashMap();
         attachments.put(Constants.TOKEN_KEY, token);
@@ -64,7 +64,7 @@ public void testInvokeWithWrongToken() throws Exception {
             Invoker invoker = Mockito.mock(Invoker.class);
             URL url = URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&token=" + token);
             when(invoker.getUrl()).thenReturn(url);
-            when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult("result"));
+            when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
 
             Map attachments = new HashMap();
             attachments.put(Constants.TOKEN_KEY, "wrongToken");
@@ -83,7 +83,7 @@ public void testInvokeWithoutToken() throws Exception {
             Invoker invoker = Mockito.mock(Invoker.class);
             URL url = URL.valueOf("test://test:11/test?accesslog=true&group=dubbo&version=1.1&token=" + token);
             when(invoker.getUrl()).thenReturn(url);
-            when(invoker.invoke(any(Invocation.class))).thenReturn(new RpcResult("result"));
+            when(invoker.invoke(any(Invocation.class))).thenReturn(new AppResponse("result"));
 
             Invocation invocation = Mockito.mock(Invocation.class);
 
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/BlockMyInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/BlockMyInvoker.java
index 28baacbf611c..7fec8d49fdb3 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/BlockMyInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/BlockMyInvoker.java
@@ -17,10 +17,11 @@
 package org.apache.dubbo.rpc.support;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 
 public class BlockMyInvoker extends MyInvoker {
 
@@ -38,19 +39,18 @@ public BlockMyInvoker(URL url, boolean hasException, long blockTime) {
 
     @Override
     public Result invoke(Invocation invocation) throws RpcException {
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         if (hasException == false) {
             try {
                 Thread.sleep(blockTime);
             } catch (InterruptedException e) {
             }
-            result.setValue("alibaba");
-            return result;
+            result.setValue("Dubbo");
         } else {
             result.setException(new RuntimeException("mocked exception"));
-            return result;
         }
 
+        return AsyncRpcResult.newDefaultAsyncResult(result, invocation);
     }
 
     public long getBlockTime() {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MockInvocation.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MockInvocation.java
index 5b7261de7b46..13a2ae244f42 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MockInvocation.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MockInvocation.java
@@ -51,6 +51,16 @@ public Map getAttachments() {
         return attachments;
     }
 
+    @Override
+    public void setAttachment(String key, String value) {
+
+    }
+
+    @Override
+    public void setAttachmentIfAbsent(String key, String value) {
+
+    }
+
     public Invoker getInvoker() {
         return null;
     }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java
index eb944c9bc1a0..1b74e6bc41b4 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java
@@ -17,11 +17,14 @@
 package org.apache.dubbo.rpc.support;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
+
+import java.util.concurrent.CompletableFuture;
 
 /**
  * MockInvoker.java
@@ -58,15 +61,14 @@ public boolean isAvailable() {
     }
 
     public Result invoke(Invocation invocation) throws RpcException {
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         if (hasException == false) {
             result.setValue("alibaba");
-            return result;
         } else {
             result.setException(new RuntimeException("mocked exception"));
-            return result;
         }
 
+        return new AsyncRpcResult(CompletableFuture.completedFuture(result), invocation);
     }
 
     @Override
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java
index 5eb4dd9205f6..0c92aea5bf59 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/CallbackServiceCodec.java
@@ -31,6 +31,7 @@
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.ProxyFactory;
 import org.apache.dubbo.rpc.RpcInvocation;
+import org.apache.dubbo.rpc.protocol.AsyncToSyncInvoker;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -144,7 +145,7 @@ private static Object referOrDestroyCallbackService(Channel channel, URL url, Cl
                 if (!isInstancesOverLimit(channel, referurl, clazz.getName(), instid, true)) {
                     @SuppressWarnings("rawtypes")
                     Invoker invoker = new ChannelWrappedInvoker(clazz, channel, referurl, String.valueOf(instid));
-                    proxy = PROXY_FACTORY.getProxy(invoker);
+                    proxy = PROXY_FACTORY.getProxy(new AsyncToSyncInvoker<>(invoker));
                     channel.setAttribute(proxyCacheKey, proxy);
                     channel.setAttribute(invokerCacheKey, invoker);
                     increaseInstanceCount(channel, countkey);
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java
index 4c78c1cceb97..5a22127d3ef2 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java
@@ -25,16 +25,20 @@
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
 import org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeClient;
 import org.apache.dubbo.remoting.transport.ClientDelegate;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.protocol.AbstractInvoker;
+import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.net.InetSocketAddress;
+import java.util.concurrent.CompletableFuture;
 
 /**
+ * Server push uses this Invoker to continuously push data to client.
  * Wrap the existing invoker on the channel.
  */
 class ChannelWrappedInvoker extends AbstractInvoker {
@@ -58,15 +62,12 @@ protected Result doInvoke(Invocation invocation) throws Throwable {
         inv.setAttachment(Constants.CALLBACK_SERVICE_KEY, serviceKey);
 
         try {
-            if (getUrl().getMethodParameter(invocation.getMethodName(), Constants.ASYNC_KEY, false)) { // may have concurrency issue
+            if (RpcUtils.isOneway(getUrl(), inv)) { // may have concurrency issue
                 currentClient.send(inv, getUrl().getMethodParameter(invocation.getMethodName(), Constants.SENT_KEY, false));
-                return new RpcResult();
-            }
-            int timeout = getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
-            if (timeout > 0) {
-                return (Result) currentClient.request(inv, timeout).get();
+                return AsyncRpcResult.newDefaultAsyncResult(invocation);
             } else {
-                return (Result) currentClient.request(inv).get();
+                CompletableFuture appResponseFuture = currentClient.request(inv).thenApply(obj -> (AppResponse) obj);
+                return new AsyncRpcResult(appResponseFuture, inv);
             }
         } catch (RpcException e) {
             throw e;
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java
index fac7c64a6caf..e6d3f84a7819 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DecodeableRpcResult.java
@@ -28,8 +28,8 @@
 import org.apache.dubbo.remoting.Decodeable;
 import org.apache.dubbo.remoting.exchange.Response;
 import org.apache.dubbo.remoting.transport.CodecSupport;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Invocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.io.IOException;
@@ -38,7 +38,7 @@
 import java.lang.reflect.Type;
 import java.util.Map;
 
-public class DecodeableRpcResult extends RpcResult implements Codec, Decodeable {
+public class DecodeableRpcResult extends AppResponse implements Codec, Decodeable {
 
     private static final Logger log = LoggerFactory.getLogger(DecodeableRpcResult.class);
 
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java
index 4093eb266d65..40c6e2912d3f 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboCountCodec.java
@@ -24,8 +24,8 @@
 import org.apache.dubbo.remoting.exchange.Request;
 import org.apache.dubbo.remoting.exchange.Response;
 import org.apache.dubbo.remoting.exchange.support.MultiMessage;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 
 import java.io.IOException;
 
@@ -75,7 +75,7 @@ private void logMessageLength(Object result, int bytes) {
             }
         } else if (result instanceof Response) {
             try {
-                ((RpcResult) ((Response) result).getResult()).setAttachment(
+                ((AppResponse) ((Response) result).getResult()).setAttachment(
                         Constants.OUTPUT_KEY, String.valueOf(bytes));
             } catch (Throwable e) {
                 /* ignore */
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java
index 5f2c61b1cae2..d8513a318060 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java
@@ -23,7 +23,7 @@
 import org.apache.dubbo.remoting.RemotingException;
 import org.apache.dubbo.remoting.TimeoutException;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
-import org.apache.dubbo.remoting.exchange.ResponseFuture;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
@@ -31,12 +31,11 @@
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
-import org.apache.dubbo.rpc.SimpleAsyncRpcResult;
 import org.apache.dubbo.rpc.protocol.AbstractInvoker;
 import org.apache.dubbo.rpc.support.RpcUtils;
 
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.locks.ReentrantLock;
 
 /**
@@ -80,32 +79,17 @@ protected Result doInvoke(final Invocation invocation) throws Throwable {
             currentClient = clients[index.getAndIncrement() % clients.length];
         }
         try {
-            boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
-            boolean isAsyncFuture = RpcUtils.isReturnTypeFuture(inv);
             boolean isOneway = RpcUtils.isOneway(getUrl(), invocation);
             int timeout = getUrl().getMethodParameter(methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
             if (isOneway) {
                 boolean isSent = getUrl().getMethodParameter(methodName, Constants.SENT_KEY, false);
                 currentClient.send(inv, isSent);
                 RpcContext.getContext().setFuture(null);
-                return new RpcResult();
-            } else if (isAsync) {
-                ResponseFuture future = currentClient.request(inv, timeout);
-                // For compatibility
-                FutureAdapter futureAdapter = new FutureAdapter<>(future);
-                RpcContext.getContext().setFuture(futureAdapter);
-
-                Result result;
-                if (isAsyncFuture) {
-                    // register resultCallback, sometimes we need the async result being processed by the filter chain.
-                    result = new AsyncRpcResult(futureAdapter, futureAdapter.getResultFuture(), false);
-                } else {
-                    result = new SimpleAsyncRpcResult(futureAdapter, futureAdapter.getResultFuture(), false);
-                }
-                return result;
+                return AsyncRpcResult.newDefaultAsyncResult(invocation);
             } else {
-                RpcContext.getContext().setFuture(null);
-                return (Result) currentClient.request(inv, timeout).get();
+                CompletableFuture appResponseFuture = currentClient.request(inv, timeout).thenApply(obj -> (AppResponse) obj);
+                RpcContext.getContext().setFuture(new FutureAdapter(appResponseFuture));
+                return new AsyncRpcResult(appResponseFuture, inv);
             }
         } catch (TimeoutException e) {
             throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e);
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
index 77443016cfb3..926a940cd5d5 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java
@@ -37,7 +37,6 @@
 import org.apache.dubbo.remoting.exchange.ExchangeServer;
 import org.apache.dubbo.remoting.exchange.Exchangers;
 import org.apache.dubbo.remoting.exchange.support.ExchangeHandlerAdapter;
-import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
@@ -59,6 +58,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Function;
 
 /**
  * dubbo protocol support.
@@ -123,16 +123,9 @@ public CompletableFuture reply(ExchangeChannel channel, Object message)
                     return null;
                 }
             }
-            RpcContext rpcContext = RpcContext.getContext();
-            rpcContext.setRemoteAddress(channel.getRemoteAddress());
+            RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());
             Result result = invoker.invoke(inv);
-
-            if (result instanceof AsyncRpcResult) {
-                return ((AsyncRpcResult) result).getResultFuture().thenApply(r -> (Object) r);
-
-            } else {
-                return CompletableFuture.completedFuture(result);
-            }
+            return result.thenApply(Function.identity());
         }
 
         @Override
@@ -382,7 +375,7 @@ private void optimizeSerialization(URL url) throws RpcException {
     }
 
     @Override
-    public  Invoker refer(Class serviceType, URL url) throws RpcException {
+    public  Invoker doRefer(Class serviceType, URL url) throws RpcException {
         optimizeSerialization(url);
 
         // create rpc invoker.
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java
index 28645410d42f..9fc47f6f9c9d 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java
@@ -16,12 +16,11 @@
  */
 package org.apache.dubbo.rpc.protocol.dubbo;
 
-import org.apache.dubbo.remoting.exchange.ResponseCallback;
-import org.apache.dubbo.remoting.exchange.ResponseFuture;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 
 import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.CompletionException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
@@ -31,45 +30,35 @@
  */
 public class FutureAdapter extends CompletableFuture {
 
-    private final ResponseFuture future;
     private CompletableFuture resultFuture;
 
-    public FutureAdapter(ResponseFuture future) {
-        this.future = future;
-        this.resultFuture = new CompletableFuture<>();
-        future.setCallback(new ResponseCallback() {
-            @Override
-            public void done(Object response) {
-                Result result = (Result) response;
-                FutureAdapter.this.resultFuture.complete(result);
-                V value = null;
-                try {
-                    value = (V) result.recreate();
-                } catch (Throwable t) {
-                    FutureAdapter.this.completeExceptionally(t);
+    public FutureAdapter(CompletableFuture future) {
+        this.resultFuture = future;
+        future.whenComplete((result, t) -> {
+            if (t != null) {
+                if (t instanceof CompletionException) {
+                    t = t.getCause();
+                }
+                this.completeExceptionally(t);
+            } else {
+                if (result.hasException()) {
+                    this.completeExceptionally(result.getException());
+                } else {
+                    this.complete((V)result.getValue());
                 }
-                FutureAdapter.this.complete(value);
-            }
-
-            @Override
-            public void caught(Throwable exception) {
-                FutureAdapter.this.completeExceptionally(exception);
             }
         });
     }
 
-    public ResponseFuture getFuture() {
-        return future;
-    }
-
+    // TODO figure out the meaning of cancel in DefaultFuture.
     @Override
     public boolean cancel(boolean mayInterruptIfRunning) {
-        return false;
+        return resultFuture.cancel(mayInterruptIfRunning);
     }
 
     @Override
     public boolean isCancelled() {
-        return false;
+        return resultFuture.isCancelled();
     }
 
     @Override
@@ -101,15 +90,4 @@ public V get(long timeout, TimeUnit unit) throws InterruptedException, Execution
         }
     }
 
-    /**
-     * FIXME
-     * This method has no need open to the the end user.
-     * Mostly user use RpcContext.getFuture() to refer the instance of this class, so the user will get a CompletableFuture, this method will rarely be noticed.
-     *
-     * @return
-     */
-    public CompletableFuture getResultFuture() {
-        return resultFuture;
-    }
-
 }
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java
index f2bc4534fdc1..c11ffca421d3 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/LazyConnectExchangeClient.java
@@ -27,9 +27,9 @@
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
 import org.apache.dubbo.remoting.exchange.ExchangeHandler;
 import org.apache.dubbo.remoting.exchange.Exchangers;
-import org.apache.dubbo.remoting.exchange.ResponseFuture;
 
 import java.net.InetSocketAddress;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantLock;
@@ -84,7 +84,7 @@ private void initClient() throws RemotingException {
     }
 
     @Override
-    public ResponseFuture request(Object request) throws RemotingException {
+    public CompletableFuture request(Object request) throws RemotingException {
         warning();
         initClient();
         return client.request(request);
@@ -105,7 +105,7 @@ public InetSocketAddress getRemoteAddress() {
     }
 
     @Override
-    public ResponseFuture request(Object request, int timeout) throws RemotingException {
+    public CompletableFuture request(Object request, int timeout) throws RemotingException {
         warning();
         initClient();
         return client.request(request, timeout);
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java
index faafe0828525..cb589e228ec8 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClient.java
@@ -24,9 +24,9 @@
 import org.apache.dubbo.remoting.RemotingException;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
 import org.apache.dubbo.remoting.exchange.ExchangeHandler;
-import org.apache.dubbo.remoting.exchange.ResponseFuture;
 
 import java.net.InetSocketAddress;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.atomic.AtomicInteger;
 
 /**
@@ -52,7 +52,7 @@ public void reset(URL url) {
     }
 
     @Override
-    public ResponseFuture request(Object request) throws RemotingException {
+    public CompletableFuture request(Object request) throws RemotingException {
         return client.request(request);
     }
 
@@ -72,7 +72,7 @@ public ChannelHandler getChannelHandler() {
     }
 
     @Override
-    public ResponseFuture request(Object request, int timeout) throws RemotingException {
+    public CompletableFuture request(Object request, int timeout) throws RemotingException {
         return client.request(request, timeout);
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
index 98283f450c87..737e73900480 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java
@@ -20,10 +20,9 @@
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
-import org.apache.dubbo.rpc.AsyncRpcResult;
-import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.ListenableFilter;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.model.ApplicationModel;
@@ -37,10 +36,14 @@
  * EventFilter
  */
 @Activate(group = Constants.CONSUMER)
-public class FutureFilter implements Filter {
+public class FutureFilter extends ListenableFilter {
 
     protected static final Logger logger = LoggerFactory.getLogger(FutureFilter.class);
 
+    public FutureFilter() {
+        super.listener = new FutureListener();
+    }
+
     @Override
     public Result invoke(final Invoker invoker, final Invocation invocation) throws RpcException {
         fireInvokeCallback(invoker, invocation);
@@ -49,37 +52,6 @@ public Result invoke(final Invoker invoker, final Invocation invocation) thro
         return invoker.invoke(invocation);
     }
 
-    @Override
-    public Result onResponse(Result result, Invoker invoker, Invocation invocation) {
-        if (result instanceof AsyncRpcResult) {
-            AsyncRpcResult asyncResult = (AsyncRpcResult) result;
-            asyncResult.thenApplyWithContext(r -> {
-                asyncCallback(invoker, invocation, r);
-                return r;
-            });
-            return asyncResult;
-        } else {
-            syncCallback(invoker, invocation, result);
-            return result;
-        }
-    }
-
-    private void syncCallback(final Invoker invoker, final Invocation invocation, final Result result) {
-        if (result.hasException()) {
-            fireThrowCallback(invoker, invocation, result.getException());
-        } else {
-            fireReturnCallback(invoker, invocation, result.getValue());
-        }
-    }
-
-    private void asyncCallback(final Invoker invoker, final Invocation invocation, Result result) {
-        if (result.hasException()) {
-            fireThrowCallback(invoker, invocation, result.getException());
-        } else {
-            fireReturnCallback(invoker, invocation, result.getValue());
-        }
-    }
-
     private void fireInvokeCallback(final Invoker invoker, final Invocation invocation) {
         final ConsumerMethodModel.AsyncMethodInfo asyncMethodInfo = getAsyncMethodInfo(invoker, invocation);
         if (asyncMethodInfo == null) {
@@ -224,4 +196,20 @@ private ConsumerMethodModel.AsyncMethodInfo getAsyncMethodInfo(Invoker invoke
 
         return asyncMethodInfo;
     }
+
+    class FutureListener implements Listener {
+        @Override
+        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+            if (result.hasException()) {
+                fireThrowCallback(invoker, invocation, result.getException());
+            } else {
+                fireReturnCallback(invoker, invocation, result.getValue());
+            }
+        }
+
+        @Override
+        public void onError(Throwable t, Invoker invoker, Invocation invocation) {
+
+        }
+    }
 }
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java
index 56fe5b8e5648..3998026b70b2 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/telnet/InvokeTelnetHandler.java
@@ -16,7 +16,6 @@
  */
 package org.apache.dubbo.rpc.protocol.dubbo.telnet;
 
-import com.alibaba.fastjson.JSON;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
@@ -24,11 +23,13 @@
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.telnet.TelnetHandler;
 import org.apache.dubbo.remoting.telnet.support.Help;
-import org.apache.dubbo.rpc.RpcResult;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ProviderMethodModel;
 import org.apache.dubbo.rpc.model.ProviderModel;
 
+import com.alibaba.fastjson.JSON;
+
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -124,7 +125,7 @@ public String telnet(Channel channel, String message) {
                     Object[] array = realize(list.toArray(), invokeMethod.getParameterTypes(),
                             invokeMethod.getGenericParameterTypes());
                     long start = System.currentTimeMillis();
-                    RpcResult result = new RpcResult();
+                    AppResponse result = new AppResponse();
                     try {
                         Object o = invokeMethod.invoke(selectedProvider.getServiceInstance(), array);
                         result.setValue(o);
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
index e2b71d05432d..9a965cd80eae 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java
@@ -19,17 +19,18 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.protocol.AsyncToSyncInvoker;
 import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 
@@ -62,7 +63,7 @@ public void test_Normal_available() {
         URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService");
         ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url);
 
-        DubboInvoker invoker = (DubboInvoker) protocol.refer(IDemoService.class, url);
+        DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url);
         Assertions.assertEquals(true, invoker.isAvailable());
         invoker.destroy();
         Assertions.assertEquals(false, invoker.isAvailable());
@@ -73,7 +74,7 @@ public void test_Normal_ChannelReadOnly() throws Exception {
         URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService");
         ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url);
 
-        DubboInvoker invoker = (DubboInvoker) protocol.refer(IDemoService.class, url);
+        DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url);
         Assertions.assertEquals(true, invoker.isAvailable());
 
         getClients(invoker)[0].setAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY, Boolean.TRUE);
@@ -91,7 +92,7 @@ public void test_normal_channel_close_wait_gracefully() throws Exception {
         Exporter exporter = ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url);
         Exporter exporter0 = ProtocolUtils.export(new DemoServiceImpl0(), IDemoService.class, url);
 
-        DubboInvoker invoker = (DubboInvoker) protocol.refer(IDemoService.class, url);
+        DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url);
 
         long start = System.currentTimeMillis();
 
@@ -113,7 +114,7 @@ public void test_NoInvokers() throws Exception {
         URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService?connections=1");
         ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url);
 
-        DubboInvoker invoker = (DubboInvoker) protocol.refer(IDemoService.class, url);
+        DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url);
 
         ExchangeClient[] clients = getClients(invoker);
         clients[0].close();
@@ -126,11 +127,10 @@ public void test_Lazy_ChannelReadOnly() throws Exception {
         URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService?lazy=true&connections=1&timeout=10000");
         ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url);
 
-        DubboInvoker invoker = (DubboInvoker) protocol.refer(IDemoService.class, url);
+        AsyncToSyncInvoker invoker = (AsyncToSyncInvoker) protocol.refer(IDemoService.class, url);
         Assertions.assertEquals(true, invoker.isAvailable());
-
         try {
-            getClients(invoker)[0].setAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY, Boolean.TRUE);
+            getClients((DubboInvoker) invoker.getInvoker())[0].setAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY, Boolean.TRUE);
             fail();
         } catch (IllegalStateException e) {
 
@@ -140,7 +140,7 @@ public void test_Lazy_ChannelReadOnly() throws Exception {
         Assertions.assertEquals("ok", service.get());
 
         Assertions.assertEquals(true, invoker.isAvailable());
-        getClients(invoker)[0].setAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY, Boolean.TRUE);
+        getClients((DubboInvoker) invoker.getInvoker())[0].setAttribute(Constants.CHANNEL_ATTRIBUTE_READONLY_KEY, Boolean.TRUE);
         Assertions.assertEquals(false, invoker.isAvailable());
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/FutureFilterTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/FutureFilterTest.java
index 7e9818d07f12..e37bd7d0dc95 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/FutureFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/FutureFilterTest.java
@@ -18,12 +18,12 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.protocol.dubbo.filter.FutureFilter;
 import org.apache.dubbo.rpc.protocol.dubbo.support.DemoService;
 
@@ -57,7 +57,7 @@ public void testSyncCallback() {
         Invoker invoker = mock(Invoker.class);
         given(invoker.isAvailable()).willReturn(true);
         given(invoker.getInterface()).willReturn(DemoService.class);
-        RpcResult result = new RpcResult();
+        AppResponse result = new AppResponse();
         result.setValue("High");
         given(invoker.invoke(invocation)).willReturn(result);
         URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1");
@@ -74,7 +74,7 @@ public void testSyncCallbackHasException() throws RpcException, Throwable {
             Invoker invoker = mock(Invoker.class);
             given(invoker.isAvailable()).willReturn(true);
             given(invoker.getInterface()).willReturn(DemoService.class);
-            RpcResult result = new RpcResult();
+            AppResponse result = new AppResponse();
             result.setException(new RuntimeException());
             given(invoker.invoke(invocation)).willReturn(result);
             URL url = URL.valueOf("test://test:11/test?group=dubbo&version=1.1&" + Constants.ON_THROW_METHOD_KEY + "=echo");
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ImplicitCallBackTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ImplicitCallBackTest.java
index 2baa67ccae64..30ffda71fdfe 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ImplicitCallBackTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ImplicitCallBackTest.java
@@ -237,7 +237,7 @@ public void test_Sync_NoFuture() throws Exception {
         Person ret = demoProxy.get(requestId);
         Assertions.assertEquals(requestId, ret.getId());
         Future pFuture = RpcContext.getContext().getFuture();
-        Assertions.assertEquals(null, pFuture);
+        Assertions.assertEquals(ret, pFuture.get());
         destroyService();
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClientTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClientTest.java
index b77e5e18b3ce..3f2c0cf21d4d 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClientTest.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/ReferenceCountExchangeClientTest.java
@@ -26,7 +26,9 @@
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.ProxyFactory;
+import org.apache.dubbo.rpc.protocol.AsyncToSyncInvoker;
 import org.apache.dubbo.rpc.protocol.dubbo.support.ProtocolUtils;
+
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
@@ -271,8 +273,7 @@ private ExchangeClient getInvokerClient(Invoker invoker) {
     }
 
     private List getInvokerClientList(Invoker invoker) {
-        @SuppressWarnings("rawtypes")
-        DubboInvoker dInvoker = (DubboInvoker) invoker;
+        @SuppressWarnings("rawtypes") DubboInvoker dInvoker = (DubboInvoker) ((AsyncToSyncInvoker) invoker).getInvoker();
         try {
             Field clientField = DubboInvoker.class.getDeclaredField("clients");
             clientField.setAccessible(true);
diff --git a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java
index 3b9239171a95..1eead54f164b 100644
--- a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java
@@ -94,7 +94,7 @@ public void run() {
 
     @Override
     @SuppressWarnings("unchecked")
-    protected  T doRefer(Class serviceType, URL url) throws RpcException {
+    protected  T getFrameworkProxy(Class serviceType, URL url) throws RpcException {
         String generic = url.getParameter(Constants.GENERIC_KEY);
         boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);
         if (isGeneric) {
diff --git a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java
index 0188a0fe329c..7b99e2d80d53 100644
--- a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java
@@ -18,8 +18,8 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
-import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.common.Version;
+import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.http.HttpBinder;
 import org.apache.dubbo.remoting.http.HttpHandler;
 import org.apache.dubbo.remoting.http.HttpServer;
@@ -110,7 +110,7 @@ private  HttpInvokerServiceExporter createExporter(T impl, Class type) {
 
     @Override
     @SuppressWarnings("unchecked")
-    protected  T doRefer(final Class serviceType, final URL url) throws RpcException {
+    protected  T getFrameworkProxy(final Class serviceType, final URL url) throws RpcException {
         final String generic = url.getParameter(Constants.GENERIC_KEY);
         final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);
 
diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java
index 1181e899d719..5a9bb845e15b 100644
--- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java
@@ -88,7 +88,7 @@ public  Exporter export(Invoker invoker) throws RpcException {
     }
 
     @Override
-    public  Invoker refer(Class serviceType, URL url) throws RpcException {
+    public  Invoker doRefer(Class serviceType, URL url) throws RpcException {
         return new InjvmInvoker(serviceType, url, url.getServiceKey(), exporterMap);
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java b/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java
index 8fa088bb95f7..eef3bf6aa583 100644
--- a/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java
@@ -18,12 +18,12 @@
 
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.protocol.AbstractInvoker;
 import org.apache.dubbo.rpc.protocol.AbstractProtocol;
 
@@ -56,7 +56,7 @@ public  Exporter export(final Invoker invoker) throws RpcException {
     }
 
     @Override
-    public  Invoker refer(final Class type, final URL url) throws RpcException {
+    public  Invoker doRefer(final Class type, final URL url) throws RpcException {
         try {
             String address = url.getAddress();
             String backup = url.getParameter(Constants.BACKUP_KEY);
@@ -73,26 +73,26 @@ public  Invoker refer(final Class type, final URL url) throws RpcExcept
                 @Override
                 protected Result doInvoke(Invocation invocation) throws Throwable {
                     try {
+                        Object value = null;
                         if (get.equals(invocation.getMethodName())) {
                             if (invocation.getArguments().length != 1) {
                                 throw new IllegalArgumentException("The memcached get method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                             }
-                            return new RpcResult(memcachedClient.get(String.valueOf(invocation.getArguments()[0])));
+                            value = memcachedClient.get(String.valueOf(invocation.getArguments()[0]));
                         } else if (set.equals(invocation.getMethodName())) {
                             if (invocation.getArguments().length != 2) {
                                 throw new IllegalArgumentException("The memcached set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                             }
                             memcachedClient.set(String.valueOf(invocation.getArguments()[0]), expiry, invocation.getArguments()[1]);
-                            return new RpcResult();
                         } else if (delete.equals(invocation.getMethodName())) {
                             if (invocation.getArguments().length != 1) {
                                 throw new IllegalArgumentException("The memcached delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                             }
                             memcachedClient.delete(String.valueOf(invocation.getArguments()[0]));
-                            return new RpcResult();
                         } else {
                             throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in memcached service.");
                         }
+                        return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
                     } catch (Throwable t) {
                         RpcException re = new RpcException("Failed to invoke memcached service method. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url + ", cause: " + t.getMessage(), t);
                         if (t instanceof TimeoutException || t instanceof SocketTimeoutException) {
diff --git a/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java b/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java
index ba35c298ec48..38aeae826ead 100644
--- a/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java
@@ -23,12 +23,12 @@
 import org.apache.dubbo.common.serialize.ObjectOutput;
 import org.apache.dubbo.common.serialize.Serialization;
 import org.apache.dubbo.common.utils.StringUtils;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.protocol.AbstractInvoker;
 import org.apache.dubbo.rpc.protocol.AbstractProtocol;
 
@@ -68,7 +68,7 @@ private Serialization getSerialization(URL url) {
     }
 
     @Override
-    public  Invoker refer(final Class type, final URL url) throws RpcException {
+    protected  Invoker doRefer(final Class type, final URL url) throws RpcException {
         try {
             GenericObjectPoolConfig config = new GenericObjectPoolConfig();
             config.setTestOnBorrow(url.getParameter("test.on.borrow", true));
@@ -119,10 +119,10 @@ protected Result doInvoke(Invocation invocation) throws Throwable {
                             }
                             byte[] value = jedis.get(String.valueOf(invocation.getArguments()[0]).getBytes());
                             if (value == null) {
-                                return new RpcResult();
+                                return AsyncRpcResult.newDefaultAsyncResult(invocation);
                             }
                             ObjectInput oin = getSerialization(url).deserialize(url, new ByteArrayInputStream(value));
-                            return new RpcResult(oin.readObject());
+                            return AsyncRpcResult.newDefaultAsyncResult(oin.readObject(), invocation);
                         } else if (set.equals(invocation.getMethodName())) {
                             if (invocation.getArguments().length != 2) {
                                 throw new IllegalArgumentException("The redis set method arguments mismatch, must be two arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
@@ -135,13 +135,13 @@ protected Result doInvoke(Invocation invocation) throws Throwable {
                             if (expiry > 1000) {
                                 jedis.expire(key, expiry / 1000);
                             }
-                            return new RpcResult();
+                            return AsyncRpcResult.newDefaultAsyncResult(invocation);
                         } else if (delete.equals(invocation.getMethodName())) {
                             if (invocation.getArguments().length != 1) {
                                 throw new IllegalArgumentException("The redis delete method arguments mismatch, must only one arguments. interface: " + type.getName() + ", method: " + invocation.getMethodName() + ", url: " + url);
                             }
                             jedis.del(String.valueOf(invocation.getArguments()[0]).getBytes());
-                            return new RpcResult();
+                            return AsyncRpcResult.newDefaultAsyncResult(invocation);
                         } else {
                             throw new UnsupportedOperationException("Unsupported method " + invocation.getMethodName() + " in redis service.");
                         }
diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
index 6265254d4c6f..09ba8c30aeef 100644
--- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java
@@ -128,7 +128,7 @@ protected  Runnable doExport(T impl, Class type, URL url) throws RpcExcept
     }
 
     @Override
-    protected  T doRefer(Class serviceType, URL url) throws RpcException {
+    protected  T getFrameworkProxy(Class serviceType, URL url) throws RpcException {
 
         // TODO more configs to add
         PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
diff --git a/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java b/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java
index 63e9fcdfff1b..823d042142e6 100644
--- a/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java
@@ -22,6 +22,7 @@
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
+
 import org.springframework.remoting.RemoteAccessException;
 import org.springframework.remoting.rmi.RmiProxyFactoryBean;
 import org.springframework.remoting.rmi.RmiServiceExporter;
@@ -69,7 +70,7 @@ public void run() {
 
     @Override
     @SuppressWarnings("unchecked")
-    protected  T doRefer(final Class serviceType, final URL url) throws RpcException {
+    protected  T getFrameworkProxy(final Class serviceType, final URL url) throws RpcException {
         final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
         final String generic = url.getParameter(Constants.GENERIC_KEY);
         final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class);
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java
index 93a5900d7530..75dd2d248dff 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java
@@ -26,9 +26,9 @@
 import org.apache.dubbo.remoting.buffer.ChannelBufferInputStream;
 import org.apache.dubbo.remoting.exchange.Request;
 import org.apache.dubbo.remoting.exchange.Response;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream;
 import org.apache.thrift.TApplicationException;
 import org.apache.thrift.TBase;
@@ -284,7 +284,7 @@ private Object decode(TProtocol protocol)
                 throw new IOException(e.getMessage(), e);
             }
 
-            RpcResult result = new RpcResult();
+            AppResponse result = new AppResponse();
 
             result.setException(new RpcException(exception.getMessage()));
 
@@ -375,7 +375,7 @@ private Object decode(TProtocol protocol)
 
             response.setId(id);
 
-            RpcResult rpcResult = new RpcResult();
+            AppResponse rpcResult = new AppResponse();
 
             if (realResult instanceof Throwable) {
                 rpcResult.setException((Throwable) realResult);
@@ -536,7 +536,7 @@ private void encodeRequest(Channel channel, ChannelBuffer buffer, Request reques
     private void encodeResponse(Channel channel, ChannelBuffer buffer, Response response)
             throws IOException {
 
-        RpcResult result = (RpcResult) response.getResult();
+        AppResponse result = (AppResponse) response.getResult();
 
         RequestData rd = CACHED_REQUEST.get(response.getId());
 
@@ -610,7 +610,7 @@ private void encodeResponse(Channel channel, ChannelBuffer buffer, Response resp
             }
 
         } else {
-            Object realResult = result.getResult();
+            Object realResult = result.getValue();
             // result field id is 0
             String fieldName = resultObj.fieldForId(0).getFieldName();
             String setMethodName = ThriftUtils.generateSetMethodName(fieldName);
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java
index fa123e232a5b..e02fac3a176e 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java
@@ -22,6 +22,8 @@
 import org.apache.dubbo.remoting.RemotingException;
 import org.apache.dubbo.remoting.TimeoutException;
 import org.apache.dubbo.remoting.exchange.ExchangeClient;
+import org.apache.dubbo.rpc.AppResponse;
+import org.apache.dubbo.rpc.AsyncRpcResult;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.Result;
@@ -29,8 +31,10 @@
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.protocol.AbstractInvoker;
+import org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter;
 
 import java.util.Set;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.locks.ReentrantLock;
 /**
  * @since 2.7.0, use https://github.com/dubbo/dubbo-rpc-native-thrift instead
@@ -85,10 +89,9 @@ protected Result doInvoke(Invocation invocation) throws Throwable {
             int timeout = getUrl().getMethodParameter(
                     methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT);
 
-            RpcContext.getContext().setFuture(null);
-
-            return (Result) currentClient.request(inv, timeout).get();
-
+            CompletableFuture appResponseFuture = currentClient.request(inv, timeout).thenApply(obj -> (AppResponse) obj);
+            RpcContext.getContext().setFuture(new FutureAdapter(appResponseFuture));
+            return new AsyncRpcResult(appResponseFuture, invocation);
         } catch (TimeoutException e) {
             throw new RpcException(RpcException.TIMEOUT_EXCEPTION, e.getMessage(), e);
         } catch (RemotingException e) {
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
index 055af6f8bb3a..61c13ccce651 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java
@@ -32,6 +32,7 @@
 import org.apache.dubbo.rpc.Exporter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
+import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProtocol;
@@ -42,6 +43,8 @@
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+
 /**
  * @since 2.7.0, use https://github.com/dubbo/dubbo-rpc-native-thrift instead
  */
@@ -83,8 +86,8 @@ public CompletableFuture reply(ExchangeChannel channel, Object msg) thro
 
                 RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress());
 
-                return CompletableFuture.completedFuture(exporter.getInvoker().invoke(inv));
-
+                Result result = exporter.getInvoker().invoke(inv);
+                return result.thenApply(Function.identity());
             }
 
             throw new RemotingException(channel,
@@ -157,7 +160,7 @@ public void destroy() {
     } // ~ end of method destroy
 
     @Override
-    public  Invoker refer(Class type, URL url) throws RpcException {
+    protected  Invoker doRefer(Class type, URL url) throws RpcException {
 
         ThriftInvoker invoker = new ThriftInvoker(type, url, getClients(url), invokers);
 
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java b/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java
index a1d5daadea86..1c781f85af29 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java
@@ -24,9 +24,9 @@
 import org.apache.dubbo.remoting.exchange.Request;
 import org.apache.dubbo.remoting.exchange.Response;
 import org.apache.dubbo.remoting.exchange.support.DefaultFuture;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.gen.thrift.Demo;
 import org.apache.dubbo.rpc.protocol.thrift.io.RandomAccessByteArrayOutputStream;
 import org.apache.thrift.TApplicationException;
@@ -186,13 +186,13 @@ public void testDecodeReplyResponse() throws Exception {
 
         Assertions.assertEquals(request.getId(), response.getId());
 
-        Assertions.assertTrue(response.getResult() instanceof RpcResult);
+        Assertions.assertTrue(response.getResult() instanceof AppResponse);
 
-        RpcResult result = (RpcResult) response.getResult();
+        AppResponse result = (AppResponse) response.getResult();
 
-        Assertions.assertTrue(result.getResult() instanceof String);
+        Assertions.assertTrue(result.getValue() instanceof String);
 
-        Assertions.assertEquals(methodResult.success, result.getResult());
+        Assertions.assertEquals(methodResult.success, result.getValue());
 
     }
 
@@ -256,9 +256,9 @@ public void testDecodeExceptionResponse() throws Exception {
 
         Response response = (Response) obj;
 
-        Assertions.assertTrue(response.getResult() instanceof RpcResult);
+        Assertions.assertTrue(response.getResult() instanceof AppResponse);
 
-        RpcResult result = (RpcResult) response.getResult();
+        AppResponse result = (AppResponse) response.getResult();
 
         Assertions.assertTrue(result.hasException());
 
@@ -275,8 +275,8 @@ public void testEncodeReplyResponse() throws Exception {
 
         Request request = createRequest();
 
-        RpcResult rpcResult = new RpcResult();
-        rpcResult.setResult("Hello, World!");
+        AppResponse rpcResult = new AppResponse();
+        rpcResult.setValue("Hello, World!");
 
         Response response = new Response();
         response.setResult(rpcResult);
@@ -333,7 +333,7 @@ public void testEncodeExceptionResponse() throws Exception {
 
         Request request = createRequest();
 
-        RpcResult rpcResult = new RpcResult();
+        AppResponse rpcResult = new AppResponse();
         String exceptionMessage = "failed";
         rpcResult.setException(new RuntimeException(exceptionMessage));
 
diff --git a/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java b/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java
index ddb270def40d..007f62beedc5 100644
--- a/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java
@@ -107,7 +107,7 @@ public void run() {
 
     @Override
     @SuppressWarnings("unchecked")
-    protected  T doRefer(final Class serviceType, final URL url) throws RpcException {
+    protected  T getFrameworkProxy(final Class serviceType, final URL url) throws RpcException {
         ClientProxyFactoryBean proxyFactoryBean = new ClientProxyFactoryBean();
         proxyFactoryBean.setAddress(url.setProtocol("http").toIdentityString());
         proxyFactoryBean.setServiceClass(serviceType);

From 596b5d55e92c40f23966c23f2456b56bdfe9f25f Mon Sep 17 00:00:00 2001
From: "ken.lj" 
Date: Wed, 8 May 2019 16:57:25 +0800
Subject: [PATCH 02/26] resolve conflicts

---
 .../dubbo/monitor/dubbo/MetricsFilter.java    | 34 ++++++++++---------
 .../rpc/protocol/AbstractProxyProtocol.java   |  2 +-
 .../org/apache/dubbo/rpc/AppResponseTest.java | 26 +++++++-------
 .../rpc/protocol/jsonrpc/JsonRpcProtocol.java |  2 +-
 .../protocol/nativethrift/ThriftProtocol.java |  3 +-
 5 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
index 90544aaf8a12..e33ae533f1c5 100644
--- a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
+++ b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
@@ -16,16 +16,6 @@
  */
 package org.apache.dubbo.monitor.dubbo;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.metrics.FastCompass;
-import com.alibaba.metrics.MetricLevel;
-import com.alibaba.metrics.MetricManager;
-import com.alibaba.metrics.MetricName;
-import com.alibaba.metrics.MetricRegistry;
-import com.alibaba.metrics.common.CollectLevel;
-import com.alibaba.metrics.common.MetricObject;
-import com.alibaba.metrics.common.MetricsCollector;
-import com.alibaba.metrics.common.MetricsCollectorFactory;
 import org.apache.dubbo.common.Constants;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
@@ -34,6 +24,7 @@
 import org.apache.dubbo.common.store.DataStore;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.monitor.MetricsService;
+import org.apache.dubbo.rpc.AppResponse;
 import org.apache.dubbo.rpc.Filter;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
@@ -41,14 +32,25 @@
 import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
-import org.apache.dubbo.rpc.RpcResult;
 import org.apache.dubbo.rpc.support.RpcUtils;
-import java.util.Collections;
-import java.util.SortedMap;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.metrics.FastCompass;
+import com.alibaba.metrics.MetricLevel;
+import com.alibaba.metrics.MetricManager;
+import com.alibaba.metrics.MetricName;
+import com.alibaba.metrics.MetricRegistry;
+import com.alibaba.metrics.common.CollectLevel;
+import com.alibaba.metrics.common.MetricObject;
+import com.alibaba.metrics.common.MetricsCollector;
+import com.alibaba.metrics.common.MetricsCollectorFactory;
+
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.SortedMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
@@ -221,12 +223,12 @@ public Result invoke(Invocation invocation) throws RpcException {
                     collector.collect(entry.getKey(), entry.getValue(), timestamp);
                 }
 
-                RpcResult result = new RpcResult();
+                AppResponse appResponse = new AppResponse();
 
                 List res = collector.build();
                 res.addAll(getThreadPoolMessage());
-                result.setValue(JSON.toJSONString(res));
-                return result;
+                appResponse.setValue(JSON.toJSONString(res));
+                return appResponse;
             }
 
             @Override
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
index e03d3800984a..8cb59f55d0a2 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java
@@ -92,7 +92,7 @@ public void unexport() {
     }
 
     @Override
-    public  Invoker doRefer(final Class type, final URL url) throws RpcException {
+    protected  Invoker doRefer(final Class type, final URL url) throws RpcException {
         final Invoker target = proxyFactory.getInvoker(getFrameworkProxy(type, url), type, url);
         Invoker invoker = new AbstractInvoker(type, url) {
             @Override
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/AppResponseTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/AppResponseTest.java
index 9c983a544a54..2fcace07a9ac 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/AppResponseTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/AppResponseTest.java
@@ -20,13 +20,13 @@
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
-public class RpcResultTest {
+public class AppResponseTest {
     @Test
-    public void testRpcResultWithNormalException() {
+    public void testAppResponseWithNormalException() {
         NullPointerException npe = new NullPointerException();
-        RpcResult rpcResult = new RpcResult(npe);
+        AppResponse appResponse = new AppResponse(npe);
 
-        StackTraceElement[] stackTrace = rpcResult.getException().getStackTrace();
+        StackTraceElement[] stackTrace = appResponse.getException().getStackTrace();
         Assertions.assertNotNull(stackTrace);
         Assertions.assertTrue(stackTrace.length > 1);
     }
@@ -35,14 +35,14 @@ public void testRpcResultWithNormalException() {
      * please run this test in Run mode
      */
     @Test
-    public void testRpcResultWithEmptyStackTraceException() {
+    public void testAppResponseWithEmptyStackTraceException() {
         Throwable throwable = buildEmptyStackTraceException();
         if (throwable == null) {
             return;
         }
-        RpcResult rpcResult = new RpcResult(throwable);
+        AppResponse appResponse = new AppResponse(throwable);
 
-        StackTraceElement[] stackTrace = rpcResult.getException().getStackTrace();
+        StackTraceElement[] stackTrace = appResponse.getException().getStackTrace();
         Assertions.assertNotNull(stackTrace);
         Assertions.assertTrue(stackTrace.length == 0);
     }
@@ -50,10 +50,10 @@ public void testRpcResultWithEmptyStackTraceException() {
     @Test
     public void testSetExceptionWithNormalException() {
         NullPointerException npe = new NullPointerException();
-        RpcResult rpcResult = new RpcResult();
-        rpcResult.setException(npe);
+        AppResponse appResponse = new AppResponse();
+        appResponse.setException(npe);
 
-        StackTraceElement[] stackTrace = rpcResult.getException().getStackTrace();
+        StackTraceElement[] stackTrace = appResponse.getException().getStackTrace();
         Assertions.assertNotNull(stackTrace);
         Assertions.assertTrue(stackTrace.length > 1);
     }
@@ -67,10 +67,10 @@ public void testSetExceptionWithEmptyStackTraceException() {
         if (throwable == null) {
             return;
         }
-        RpcResult rpcResult = new RpcResult();
-        rpcResult.setException(throwable);
+        AppResponse appResponse = new AppResponse();
+        appResponse.setException(throwable);
 
-        StackTraceElement[] stackTrace = rpcResult.getException().getStackTrace();
+        StackTraceElement[] stackTrace = appResponse.getException().getStackTrace();
         Assertions.assertNotNull(stackTrace);
         Assertions.assertTrue(stackTrace.length == 0);
     }
diff --git a/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java b/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java
index aaba802cd4ec..1708f092fb6c 100644
--- a/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java
@@ -115,7 +115,7 @@ protected  Runnable doExport(T impl, Class type, URL url) throws RpcExcept
 
     @SuppressWarnings("unchecked")
     @Override
-    protected  T doRefer(final Class serviceType, URL url) throws RpcException {
+    protected  T getFrameworkProxy(final Class serviceType, URL url) throws RpcException {
         JsonProxyFactoryBean jsonProxyFactoryBean = new JsonProxyFactoryBean();
         jsonProxyFactoryBean.setServiceUrl(url.setProtocol("http").toIdentityString());
         jsonProxyFactoryBean.setServiceInterface(serviceType);
diff --git a/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java
index c869c60337b3..16dd3c958255 100644
--- a/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java
+++ b/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java
@@ -20,6 +20,7 @@
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol;
+
 import org.apache.thrift.TException;
 import org.apache.thrift.TMultiplexedProcessor;
 import org.apache.thrift.TProcessor;
@@ -68,7 +69,7 @@ protected  Runnable doExport(T impl, Class type, URL url) throws RpcExcept
     }
 
     @Override
-    protected  T doRefer(Class type, URL url) throws RpcException {
+    protected  T getFrameworkProxy(Class type, URL url) throws RpcException {
         return doReferFrameAndCompact(type, url);
     }
 

From 8143d4e41f7a3bc185aafd2b17e97ad539a5d7c6 Mon Sep 17 00:00:00 2001
From: "ken.lj" 
Date: Fri, 19 Apr 2019 11:47:20 +0800
Subject: [PATCH 03/26] Rename some variables to avoid possible confusion
 between Result and AppResponse. (#3889)

Clear that the `Result` of the call back is actually an `AppResponse`.
---
 .../support/FailsafeClusterInvoker.java       |  2 +-
 .../org/apache/dubbo/remoting/MockResult.java |  2 +-
 .../org/apache/dubbo/rpc/AsyncRpcResult.java  | 26 +++++++++----------
 .../java/org/apache/dubbo/rpc/Filter.java     |  2 +-
 .../dubbo/rpc/filter/ActiveLimitFilter.java   |  2 +-
 .../dubbo/rpc/filter/CompatibleFilter.java    |  8 +++---
 .../rpc/filter/ConsumerContextFilter.java     |  4 +--
 .../dubbo/rpc/filter/ContextFilter.java       |  4 +--
 .../dubbo/rpc/filter/ExceptionFilter.java     |  8 +++---
 .../dubbo/rpc/filter/ExecuteLimitFilter.java  |  2 +-
 .../dubbo/rpc/filter/GenericFilter.java       | 14 +++++-----
 .../dubbo/rpc/filter/GenericImplFilter.java   | 18 ++++++-------
 .../dubbo/rpc/filter/TimeoutFilter.java       |  2 +-
 .../filter/CompatibleFilterFilterTest.java    | 12 ++++-----
 .../dubbo/rpc/filter/ExceptionFilterTest.java | 25 +++++++++---------
 .../dubbo/rpc/filter/GenericFilterTest.java   |  8 +++---
 .../rpc/protocol/thrift/ThriftCodec.java      |  8 +++---
 .../rpc/protocol/thrift/ThriftCodecTest.java  | 14 +++++-----
 18 files changed, 80 insertions(+), 81 deletions(-)

diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java
index 061068a71b0f..539686ed0e4a 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/FailsafeClusterInvoker.java
@@ -29,7 +29,7 @@
 import java.util.List;
 
 /**
- * When invoke fails, log the error message and ignore this error by returning an empty RpcResult.
+ * When invoke fails, log the error message and ignore this error by returning an empty Result.
  * Usually used to write audit logs and other operations
  *
  * Fail-safe
diff --git a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/MockResult.java b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/MockResult.java
index 78369527efcb..c353621056a6 100644
--- a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/MockResult.java
+++ b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/MockResult.java
@@ -19,7 +19,7 @@
 import java.io.Serializable;
 
 /**
- * RpcResult.
+ * AppResponse.
  */
 
 public class MockResult implements Serializable {
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java
index e48b7130159f..789cbe74bdf7 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java
@@ -47,7 +47,7 @@ public AsyncRpcResult(CompletableFuture future, Invocation invocati
 
     @Override
     public Object getValue() {
-        return getRpcResult().getValue();
+        return getAppResponse().getValue();
     }
 
     @Override
@@ -57,7 +57,7 @@ public void setValue(Object value) {
 
     @Override
     public Throwable getException() {
-        return getRpcResult().getException();
+        return getAppResponse().getException();
     }
 
     @Override
@@ -67,7 +67,7 @@ public void setException(Throwable t) {
 
     @Override
     public boolean hasException() {
-        return getRpcResult().hasException();
+        return getAppResponse().hasException();
     }
 
     public CompletableFuture getResponseFuture() {
@@ -78,7 +78,7 @@ public void setResponseFuture(CompletableFuture responseFuture) {
         this.responseFuture = responseFuture;
     }
 
-    public Result getRpcResult() {
+    public Result getAppResponse() {
         try {
             if (responseFuture.isDone()) {
                 return responseFuture.get();
@@ -94,9 +94,9 @@ public Result getRpcResult() {
     public Object recreate() throws Throwable {
         RpcInvocation rpcInvocation = (RpcInvocation) invocation;
         if (InvokeMode.FUTURE == rpcInvocation.getInvokeMode()) {
-            AppResponse rpcResult = new AppResponse();
+            AppResponse appResponse = new AppResponse();
             CompletableFuture future = new CompletableFuture<>();
-            rpcResult.setValue(future);
+            appResponse.setValue(future);
             responseFuture.whenComplete((result, t) -> {
                 if (t != null) {
                     if (t instanceof CompletionException) {
@@ -111,7 +111,7 @@ public Object recreate() throws Throwable {
                     }
                 }
             });
-            return rpcResult.recreate();
+            return appResponse.recreate();
         } else if (responseFuture.isDone()) {
             return responseFuture.get().recreate();
         }
@@ -135,32 +135,32 @@ public  CompletableFuture thenApply(Function fn) {
 
     @Override
     public Map getAttachments() {
-        return getRpcResult().getAttachments();
+        return getAppResponse().getAttachments();
     }
 
     @Override
     public void setAttachments(Map map) {
-        getRpcResult().setAttachments(map);
+        getAppResponse().setAttachments(map);
     }
 
     @Override
     public void addAttachments(Map map) {
-        getRpcResult().addAttachments(map);
+        getAppResponse().addAttachments(map);
     }
 
     @Override
     public String getAttachment(String key) {
-        return getRpcResult().getAttachment(key);
+        return getAppResponse().getAttachment(key);
     }
 
     @Override
     public String getAttachment(String key, String defaultValue) {
-        return getRpcResult().getAttachment(key, defaultValue);
+        return getAppResponse().getAttachment(key, defaultValue);
     }
 
     @Override
     public void setAttachment(String key, String value) {
-        getRpcResult().setAttachment(key, value);
+        getAppResponse().setAttachment(key, value);
     }
 
     /**
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java
index 7c634481d7e5..344548829044 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java
@@ -49,7 +49,7 @@ public interface Filter {
 
     interface Listener {
 
-        void onResponse(Result result, Invoker invoker, Invocation invocation);
+        void onResponse(Result appResponse, Invoker invoker, Invocation invocation);
 
         void onError(Throwable t, Invoker invoker, Invocation invocation);
     }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
index fe692af565f7..1fd0a8b9b33c 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java
@@ -83,7 +83,7 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
 
     static class ActiveLimitListener implements Listener {
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
             String methodName = invocation.getMethodName();
             URL url = invoker.getUrl();
             int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
index ad1a8a2492b5..2eb67b4df29a 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
@@ -60,9 +60,9 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
 
     static class CompatibleListener implements Listener {
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
-            if (!invocation.getMethodName().startsWith("$") && !result.hasException()) {
-                Object value = result.getValue();
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
+            if (!invocation.getMethodName().startsWith("$") && !appResponse.hasException()) {
+                Object value = appResponse.getValue();
                 if (value != null) {
                     try {
                         Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
@@ -81,7 +81,7 @@ public void onResponse(Result result, Invoker invoker, Invocation invocation)
                             newValue = value;
                         }
                         if (newValue != value) {
-                            result.setValue(newValue);
+                            appResponse.setValue(newValue);
                         }
                     } catch (Throwable t) {
                         logger.warn(t.getMessage(), t);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
index a2005e21e1a3..794b6fdd9875 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
@@ -62,8 +62,8 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
 
     static class ConsumerContextListener implements Listener {
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
-            RpcContext.getServerContext().setAttachments(result.getAttachments());
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
+            RpcContext.getServerContext().setAttachments(appResponse.getAttachments());
         }
 
         @Override
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
index df135a648948..1a8e40e4b877 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
@@ -92,9 +92,9 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
 
     static class ContextListener implements Listener {
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
             // pass attachments to result
-            result.addAttachments(RpcContext.getServerContext().getAttachments());
+            appResponse.addAttachments(RpcContext.getServerContext().getAttachments());
         }
 
         @Override
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
index 1cb9f87d4887..4fcf54008e42 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
@@ -60,10 +60,10 @@ static class ExceptionListener implements Listener {
         private Logger logger = LoggerFactory.getLogger(ExceptionListener.class);
 
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
-            if (result.hasException() && GenericService.class != invoker.getInterface()) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
+            if (appResponse.hasException() && GenericService.class != invoker.getInterface()) {
                 try {
-                    Throwable exception = result.getException();
+                    Throwable exception = appResponse.getException();
 
                     // directly throw if it's checked exception
                     if (!(exception instanceof RuntimeException) && (exception instanceof Exception)) {
@@ -102,7 +102,7 @@ public void onResponse(Result result, Invoker invoker, Invocation invocation)
                     }
 
                     // otherwise, wrap with RuntimeException and throw back to the client
-                    result.setException(new RuntimeException(StringUtils.toString(exception)));
+                    appResponse.setException(new RuntimeException(StringUtils.toString(exception)));
                     return;
                 } catch (Throwable e) {
                     logger.warn("Fail to ExceptionFilter when called by " + RpcContext.getContext().getRemoteHost() + ". service: " + invoker.getInterface().getName() + ", method: " + invocation.getMethodName() + ", exception: " + e.getClass().getName() + ": " + e.getMessage(), e);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java
index c1b2eb5e6bc7..8456a36ff7cb 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java
@@ -68,7 +68,7 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
 
     static class ExecuteLimitListener implements Listener {
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
             RpcStatus.endCount(invoker.getUrl(), invocation.getMethodName(), getElapsed(invocation), true);
         }
 
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
index 5c86cae65779..190f8a1fd2bf 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
@@ -124,7 +124,7 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException {
     static class GenericListener implements Listener {
 
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation inv) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation inv) {
             if ((inv.getMethodName().equals(Constants.$INVOKE) || inv.getMethodName().equals(Constants.$INVOKE_ASYNC))
                     && inv.getArguments() != null
                     && inv.getArguments().length == 3
@@ -135,21 +135,21 @@ public void onResponse(Result result, Invoker invoker, Invocation inv) {
                     generic = RpcContext.getContext().getAttachment(Constants.GENERIC_KEY);
                 }
 
-                if (result.hasException() && !(result.getException() instanceof GenericException)) {
-                    result.setException(new GenericException(result.getException()));
+                if (appResponse.hasException() && !(appResponse.getException() instanceof GenericException)) {
+                    appResponse.setException(new GenericException(appResponse.getException()));
                 }
                 if (ProtocolUtils.isJavaGenericSerialization(generic)) {
                     try {
                         UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
-                        ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA).serialize(null, os).writeObject(result.getValue());
-                        result.setValue(os.toByteArray());
+                        ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA).serialize(null, os).writeObject(appResponse.getValue());
+                        appResponse.setValue(os.toByteArray());
                     } catch (IOException e) {
                         throw new RpcException("Serialize result failed.", e);
                     }
                 } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
-                    result.setValue(JavaBeanSerializeUtil.serialize(result.getValue(), JavaBeanAccessor.METHOD));
+                    appResponse.setValue(JavaBeanSerializeUtil.serialize(appResponse.getValue(), JavaBeanAccessor.METHOD));
                 } else {
-                    result.setValue(PojoUtils.generalize(result.getValue()));
+                    appResponse.setValue(PojoUtils.generalize(appResponse.getValue()));
                 }
             }
         }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
index f9caf44f069b..d6981e9aa55d 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java
@@ -121,34 +121,34 @@ private void error(String generic, String expected, String actual) throws RpcExc
 
     static class GenericImplListener implements Listener {
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
             String generic = invoker.getUrl().getParameter(Constants.GENERIC_KEY);
             String methodName = invocation.getMethodName();
             Class[] parameterTypes = invocation.getParameterTypes();
             if (ProtocolUtils.isGeneric(generic)
                     && (!Constants.$INVOKE.equals(invocation.getMethodName()) && !Constants.$INVOKE_ASYNC.equals(invocation.getMethodName()))
                     && invocation instanceof RpcInvocation) {
-                if (!result.hasException()) {
-                    Object value = result.getValue();
+                if (!appResponse.hasException()) {
+                    Object value = appResponse.getValue();
                     try {
                         Method method = invoker.getInterface().getMethod(methodName, parameterTypes);
                         if (ProtocolUtils.isBeanGenericSerialization(generic)) {
                             if (value == null) {
-                                result.setValue(value);
+                                appResponse.setValue(value);
                             } else if (value instanceof JavaBeanDescriptor) {
-                                result.setValue(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
+                                appResponse.setValue(JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) value));
                             } else {
                                 throw new RpcException("The type of result value is " + value.getClass().getName() + " other than " + JavaBeanDescriptor.class.getName() + ", and the result is " + value);
                             }
                         } else {
                             Type[] types = ReflectUtils.getReturnTypes(method);
-                            result.setValue(PojoUtils.realize(value, (Class) types[0], types[1]));
+                            appResponse.setValue(PojoUtils.realize(value, (Class) types[0], types[1]));
                         }
                     } catch (NoSuchMethodException e) {
                         throw new RpcException(e.getMessage(), e);
                     }
-                } else if (result.getException() instanceof GenericException) {
-                    GenericException exception = (GenericException) result.getException();
+                } else if (appResponse.getException() instanceof GenericException) {
+                    GenericException exception = (GenericException) appResponse.getException();
                     try {
                         String className = exception.getExceptionClass();
                         Class clazz = ReflectUtils.forName(className);
@@ -177,7 +177,7 @@ public void onResponse(Result result, Invoker invoker, Invocation invocation)
                             } catch (Throwable e) {
                                 logger.warn(e.getMessage(), e);
                             }
-                            result.setException(targetException);
+                            appResponse.setException(targetException);
                         } else if (lastException != null) {
                             throw lastException;
                         }
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java
index b6335823d8ef..c51cd3df4275 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java
@@ -51,7 +51,7 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
     static class TimeoutListener implements Listener {
 
         @Override
-        public void onResponse(Result result, Invoker invoker, Invocation invocation) {
+        public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
             String startAttach = invocation.getAttachment(TIMEOUT_FILTER_START_TIME);
             if (startAttach != null) {
                 long elapsed = System.currentTimeMillis() - Long.valueOf(startAttach);
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java
index e16dfbd8f610..709401d42785 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/CompatibleFilterFilterTest.java
@@ -105,9 +105,9 @@ public void testInvokerJsonPojoSerialization() throws Exception {
         given(invoker.getUrl()).willReturn(url);
 
         Result asyncResult = compatibleFilter.invoke(invoker, invocation);
-        Result rpcResult = asyncResult.get();
-        compatibleFilter.listener().onResponse(rpcResult, invoker, invocation);
-        assertEquals(Type.High, rpcResult.getValue());
+        AppResponse appResponse = (AppResponse) asyncResult.get();
+        compatibleFilter.listener().onResponse(appResponse, invoker, invocation);
+        assertEquals(Type.High, appResponse.getValue());
     }
 
     @Test
@@ -127,9 +127,9 @@ public void testInvokerNonJsonEnumSerialization() throws Exception {
         given(invoker.getUrl()).willReturn(url);
 
         Result asyncResult = compatibleFilter.invoke(invoker, invocation);
-        Result rpcResult = asyncResult.get();
-        compatibleFilter.listener().onResponse(rpcResult, invoker, invocation);
-        assertEquals(Type.High, rpcResult.getValue());
+        AppResponse appResponse = (AppResponse) asyncResult.get();
+        compatibleFilter.listener().onResponse(appResponse, invoker, invocation);
+        assertEquals(Type.High, appResponse.getValue());
     }
 
     @Test
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java
index 964e06ecb153..49af0c0951ee 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java
@@ -28,7 +28,6 @@
 import org.apache.dubbo.rpc.support.LocalException;
 
 import com.alibaba.com.caucho.hessian.HessianException;
-
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -80,16 +79,16 @@ public void testJavaException() {
         ExceptionFilter exceptionFilter = new ExceptionFilter();
         RpcInvocation invocation = new RpcInvocation("sayHello", new Class[]{String.class}, new Object[]{"world"});
 
-        AppResponse rpcResult = new AppResponse();
-        rpcResult.setException(new IllegalArgumentException("java"));
+        AppResponse appResponse = new AppResponse();
+        appResponse.setException(new IllegalArgumentException("java"));
 
         Invoker invoker = mock(Invoker.class);
-        when(invoker.invoke(invocation)).thenReturn(rpcResult);
+        when(invoker.invoke(invocation)).thenReturn(appResponse);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
         Result newResult = exceptionFilter.invoke(invoker, invocation);
 
-        Assertions.assertEquals(rpcResult.getException(), newResult.getException());
+        Assertions.assertEquals(appResponse.getException(), newResult.getException());
 
     }
 
@@ -100,16 +99,16 @@ public void testRuntimeException() {
         ExceptionFilter exceptionFilter = new ExceptionFilter();
         RpcInvocation invocation = new RpcInvocation("sayHello", new Class[]{String.class}, new Object[]{"world"});
 
-        AppResponse rpcResult = new AppResponse();
-        rpcResult.setException(new LocalException("localException"));
+        AppResponse appResponse = new AppResponse();
+        appResponse.setException(new LocalException("localException"));
 
         Invoker invoker = mock(Invoker.class);
-        when(invoker.invoke(invocation)).thenReturn(rpcResult);
+        when(invoker.invoke(invocation)).thenReturn(appResponse);
         when(invoker.getInterface()).thenReturn(DemoService.class);
 
         Result newResult = exceptionFilter.invoke(invoker, invocation);
 
-        Assertions.assertEquals(rpcResult.getException(), newResult.getException());
+        Assertions.assertEquals(appResponse.getException(), newResult.getException());
 
     }
 
@@ -131,12 +130,12 @@ public void testConvertToRunTimeException() throws Exception {
 
         Result asyncResult = exceptionFilter.invoke(invoker, invocation);
 
-        Result rpcResult = asyncResult.get();
-        exceptionFilter.listener().onResponse(rpcResult, invoker, invocation);
+        AppResponse appResponse = (AppResponse) asyncResult.get();
+        exceptionFilter.listener().onResponse(appResponse, invoker, invocation);
 
-        Assertions.assertFalse(rpcResult.getException() instanceof HessianException);
+        Assertions.assertFalse(appResponse.getException() instanceof HessianException);
 
-        Assertions.assertEquals(rpcResult.getException().getClass(), RuntimeException.class);
+        Assertions.assertEquals(appResponse.getException().getClass(), RuntimeException.class);
     }
 
 }
\ No newline at end of file
diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java
index f2358ddaeca1..35fae848e33b 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericFilterTest.java
@@ -64,10 +64,10 @@ public void testInvokeWithDefault() throws Exception {
 
         Result asyncResult = genericFilter.invoke(invoker, invocation);
 
-        Result rpcResult = asyncResult.get();
-        genericFilter.listener().onResponse(rpcResult, invoker, invocation);
-        Assertions.assertEquals(HashMap.class, rpcResult.getValue().getClass());
-        Assertions.assertEquals(10, ((HashMap) rpcResult.getValue()).get("age"));
+        AppResponse appResponse = (AppResponse) asyncResult.get();
+        genericFilter.listener().onResponse(appResponse, invoker, invocation);
+        Assertions.assertEquals(HashMap.class, appResponse.getValue().getClass());
+        Assertions.assertEquals(10, ((HashMap) appResponse.getValue()).get("age"));
 
     }
 
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java
index 75dd2d248dff..0c835d2d951f 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodec.java
@@ -375,15 +375,15 @@ private Object decode(TProtocol protocol)
 
             response.setId(id);
 
-            AppResponse rpcResult = new AppResponse();
+            AppResponse appResponse = new AppResponse();
 
             if (realResult instanceof Throwable) {
-                rpcResult.setException((Throwable) realResult);
+                appResponse.setException((Throwable) realResult);
             } else {
-                rpcResult.setValue(realResult);
+                appResponse.setValue(realResult);
             }
 
-            response.setResult(rpcResult);
+            response.setResult(appResponse);
 
             return response;
 
diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java b/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java
index 1c781f85af29..9c1b1c4518c3 100644
--- a/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java
+++ b/dubbo-rpc/dubbo-rpc-thrift/src/test/java/org/apache/dubbo/rpc/protocol/thrift/ThriftCodecTest.java
@@ -275,11 +275,11 @@ public void testEncodeReplyResponse() throws Exception {
 
         Request request = createRequest();
 
-        AppResponse rpcResult = new AppResponse();
-        rpcResult.setValue("Hello, World!");
+        AppResponse appResponse = new AppResponse();
+        appResponse.setValue("Hello, World!");
 
         Response response = new Response();
-        response.setResult(rpcResult);
+        response.setResult(appResponse);
         response.setId(request.getId());
         ChannelBuffer bos = ChannelBuffers.dynamicBuffer(1024);
 
@@ -321,7 +321,7 @@ public void testEncodeReplyResponse() throws Exception {
         result.read(protocol);
         protocol.readMessageEnd();
 
-        Assertions.assertEquals(rpcResult.getValue(), result.getSuccess());
+        Assertions.assertEquals(appResponse.getValue(), result.getSuccess());
     }
 
     @Test
@@ -333,12 +333,12 @@ public void testEncodeExceptionResponse() throws Exception {
 
         Request request = createRequest();
 
-        AppResponse rpcResult = new AppResponse();
+        AppResponse appResponse = new AppResponse();
         String exceptionMessage = "failed";
-        rpcResult.setException(new RuntimeException(exceptionMessage));
+        appResponse.setException(new RuntimeException(exceptionMessage));
 
         Response response = new Response();
-        response.setResult(rpcResult);
+        response.setResult(appResponse);
         response.setId(request.getId());
         ChannelBuffer bos = ChannelBuffers.dynamicBuffer(1024);
 

From 64081c6618ed0613a874536b5b15a0303e63837e Mon Sep 17 00:00:00 2001
From: "ken.lj" 
Date: Wed, 24 Apr 2019 11:02:49 +0800
Subject: [PATCH 04/26] Result implements future and keep Filter backward
 compatibility. (#3916)

---
 .../java/com/alibaba/dubbo/rpc/Result.java    |  34 +++---
 .../org/apache/dubbo/rpc/AbstractResult.java  |  25 +++++
 .../org/apache/dubbo/rpc/AppResponse.java     |  26 ++---
 .../org/apache/dubbo/rpc/AsyncRpcResult.java  | 102 +++++++++++-------
 .../java/org/apache/dubbo/rpc/Filter.java     |  13 +++
 .../java/org/apache/dubbo/rpc/Result.java     |  20 ++--
 .../rpc/protocol/ProtocolFilterWrapper.java   |   2 +
 .../dubbo/rpc/proxy/AbstractProxyInvoker.java |   7 +-
 .../dubbo/rpc/filter/ExceptionFilterTest.java |   5 +-
 .../rpc/filter/GenericImplFilterTest.java     |   5 +-
 .../apache/dubbo/rpc/support/MyInvoker.java   |   4 +-
 .../protocol/dubbo/ChannelWrappedInvoker.java |  12 ++-
 .../rpc/protocol/dubbo/DubboInvoker.java      |  14 ++-
 .../rpc/protocol/dubbo/DubboProtocol.java     |   2 +-
 .../rpc/protocol/dubbo/FutureAdapter.java     |  14 +--
 .../rpc/protocol/thrift/ThriftInvoker.java    |   9 +-
 16 files changed, 180 insertions(+), 114 deletions(-)
 create mode 100644 dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java

diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java
index 22531301be17..07f5df9bf5a1 100644
--- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java
+++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/Result.java
@@ -17,11 +17,7 @@
 
 package com.alibaba.dubbo.rpc;
 
-import org.apache.dubbo.rpc.AppResponse;
-
 import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import java.util.function.Function;
 
 @Deprecated
@@ -37,23 +33,15 @@ default void setException(Throwable t) {
 
     }
 
-    @Override
-    default org.apache.dubbo.rpc.Result thenApplyWithContext(Function fn) {
-        return this;
-    }
-
-    @Override
-    default  CompletableFuture thenApply(Function fn) {
-        return null;
-    }
+    abstract class AbstractResult extends org.apache.dubbo.rpc.AbstractResult implements Result {
 
-    @Override
-    default org.apache.dubbo.rpc.Result get() throws InterruptedException, ExecutionException {
-        return this;
+        @Override
+        public org.apache.dubbo.rpc.Result thenApplyWithContext(Function fn) {
+            return null;
+        }
     }
 
-
-    class CompatibleResult implements Result {
+    class CompatibleResult extends AbstractResult {
         private org.apache.dubbo.rpc.Result delegate;
 
         public CompatibleResult(org.apache.dubbo.rpc.Result result) {
@@ -69,11 +57,21 @@ public Object getValue() {
             return delegate.getValue();
         }
 
+        @Override
+        public void setValue(Object value) {
+            delegate.setValue(value);
+        }
+
         @Override
         public Throwable getException() {
             return delegate.getException();
         }
 
+        @Override
+        public void setException(Throwable t) {
+            delegate.setException(t);
+        }
+
         @Override
         public boolean hasException() {
             return delegate.hasException();
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java
new file mode 100644
index 000000000000..2db743d57166
--- /dev/null
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AbstractResult.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.dubbo.rpc;
+
+import java.util.concurrent.CompletableFuture;
+
+/**
+ *
+ */
+public abstract class AbstractResult extends CompletableFuture implements Result {
+}
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java
index 6ede9d4ee5be..16e938095a58 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AppResponse.java
@@ -19,8 +19,6 @@
 import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
 import java.util.function.Function;
 
 /**
@@ -30,21 +28,19 @@
  *     
  • AppResponse only simply represents the business result
  • * * - * The relationship between them can be reflected in the definition of AsyncRpcResult: + * The relationship between them can be described as follow, an abstraction of the definition of AsyncRpcResult: *
      *  {@code
    - *   Public class AsyncRpcResult implements Result {
    - *      private CompletableFuture  resultFuture;
    + *   Public class AsyncRpcResult implements CompletionStage {
      *       ......
    - *   }
      *  }
      * 
    - * - * In theory, AppResponse does not need to implement the {@link Result} interface, this is done mainly for compatibility purpose. + * AsyncRpcResult is a future representing an unfinished RPC call, while AppResponse is the actual return type of this call. + * In theory, AppResponse does'n have to implement the {@link Result} interface, this is done mainly for compatibility purpose. * * @serial Do not change the class name and properties. */ -public class AppResponse implements Result, Serializable { +public class AppResponse extends AbstractResult implements Serializable { private static final long serialVersionUID = -6925924956850004727L; @@ -139,17 +135,7 @@ public void setAttachment(String key, String value) { } @Override - public Result thenApplyWithContext(Function fn) { - throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly."); - } - - @Override - public CompletableFuture thenApply(Function fn) { - throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly."); - } - - @Override - public Result get() throws InterruptedException, ExecutionException { + public Result thenApplyWithContext(Function fn) { throw new UnsupportedOperationException("AppResponse represents an concrete business response, there will be no status changes, you should get internal values directly."); } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java index 789cbe74bdf7..e15053ac7fa1 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java @@ -22,10 +22,9 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutionException; import java.util.function.Function; -public class AsyncRpcResult implements Result { +public class AsyncRpcResult extends AbstractResult { private static final Logger logger = LoggerFactory.getLogger(AsyncRpcResult.class); /** @@ -35,16 +34,25 @@ public class AsyncRpcResult implements Result { private RpcContext storedContext; private RpcContext storedServerContext; - private CompletableFuture responseFuture; private Invocation invocation; - public AsyncRpcResult(CompletableFuture future, Invocation invocation) { - this.responseFuture = future; + public AsyncRpcResult(Invocation invocation) { this.invocation = invocation; this.storedContext = RpcContext.getContext(); this.storedServerContext = RpcContext.getServerContext(); } + public AsyncRpcResult(AsyncRpcResult asyncRpcResult) { + this.invocation = asyncRpcResult.getInvocation(); + this.storedContext = asyncRpcResult.getStoredContext(); + this.storedServerContext = asyncRpcResult.getStoredServerContext(); + } + + /** + * Notice the return type of {@link #getValue} is the actual type of the RPC method, not {@link AppResponse} + * + * @return + */ @Override public Object getValue() { return getAppResponse().getValue(); @@ -52,7 +60,9 @@ public Object getValue() { @Override public void setValue(Object value) { - + AppResponse appResponse = new AppResponse(); + appResponse.setValue(value); + this.complete(appResponse); } @Override @@ -62,7 +72,9 @@ public Throwable getException() { @Override public void setException(Throwable t) { - + AppResponse appResponse = new AppResponse(); + appResponse.setException(t); + this.complete(appResponse); } @Override @@ -70,18 +82,10 @@ public boolean hasException() { return getAppResponse().hasException(); } - public CompletableFuture getResponseFuture() { - return responseFuture; - } - - public void setResponseFuture(CompletableFuture responseFuture) { - this.responseFuture = responseFuture; - } - public Result getAppResponse() { try { - if (responseFuture.isDone()) { - return responseFuture.get(); + if (this.isDone()) { + return this.get(); } } catch (Exception e) { // This should never happen; @@ -97,7 +101,7 @@ public Object recreate() throws Throwable { AppResponse appResponse = new AppResponse(); CompletableFuture future = new CompletableFuture<>(); appResponse.setValue(future); - responseFuture.whenComplete((result, t) -> { + this.whenComplete((result, t) -> { if (t != null) { if (t instanceof CompletionException) { t = t.getCause(); @@ -112,25 +116,27 @@ public Object recreate() throws Throwable { } }); return appResponse.recreate(); - } else if (responseFuture.isDone()) { - return responseFuture.get().recreate(); + } else if (this.isDone()) { + return this.get().recreate(); } return (new AppResponse()).recreate(); } - public Result get() throws InterruptedException, ExecutionException { - return responseFuture.get(); + public Result thenApplyWithContext(Function fn) { + CompletableFuture future = this.thenApply(fn.compose(beforeContext).andThen(afterContext)); + AsyncRpcResult nextAsyncRpcResult = new AsyncRpcResult(this); + nextAsyncRpcResult.subscribeTo(future); + return nextAsyncRpcResult; } - @Override - public Result thenApplyWithContext(Function fn) { - this.responseFuture = responseFuture.thenApply(fn.compose(beforeContext).andThen(afterContext)); - return this; - } - - @Override - public CompletableFuture thenApply(Function fn) { - return this.responseFuture.thenApply(fn); + public void subscribeTo(CompletableFuture future) { + future.whenComplete((obj, t) -> { + if (t != null) { + this.completeExceptionally(t); + } else { + this.complete((Result) obj); + } + }); } @Override @@ -163,13 +169,25 @@ public void setAttachment(String key, String value) { getAppResponse().setAttachment(key, value); } + public RpcContext getStoredContext() { + return storedContext; + } + + public RpcContext getStoredServerContext() { + return storedServerContext; + } + + public Invocation getInvocation() { + return invocation; + } + /** * tmp context to use when the thread switch to Dubbo thread. */ private RpcContext tmpContext; private RpcContext tmpServerContext; - private Function beforeContext = (appResponse) -> { + private Function beforeContext = (appResponse) -> { tmpContext = RpcContext.getContext(); tmpServerContext = RpcContext.getServerContext(); RpcContext.restoreContext(storedContext); @@ -177,7 +195,7 @@ public void setAttachment(String key, String value) { return appResponse; }; - private Function afterContext = (appResponse) -> { + private Function afterContext = (appResponse) -> { RpcContext.restoreContext(tmpContext); RpcContext.restoreServerContext(tmpServerContext); return appResponse; @@ -186,8 +204,10 @@ public void setAttachment(String key, String value) { /** * Some utility methods used to quickly generate default AsyncRpcResult instance. */ - public static AsyncRpcResult newDefaultAsyncResult(AppResponse result, Invocation invocation) { - return new AsyncRpcResult(CompletableFuture.completedFuture(result), invocation); + public static AsyncRpcResult newDefaultAsyncResult(AppResponse appResponse, Invocation invocation) { + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation); + asyncRpcResult.complete(appResponse); + return asyncRpcResult; } public static AsyncRpcResult newDefaultAsyncResult(Invocation invocation) { @@ -203,15 +223,15 @@ public static AsyncRpcResult newDefaultAsyncResult(Throwable t, Invocation invoc } public static AsyncRpcResult newDefaultAsyncResult(Object value, Throwable t, Invocation invocation) { - CompletableFuture future = new CompletableFuture<>(); - AppResponse result = new AppResponse(); + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation); + AppResponse appResponse = new AppResponse(); if (t != null) { - result.setException(t); + appResponse.setException(t); } else { - result.setValue(value); + appResponse.setValue(value); } - future.complete(result); - return new AsyncRpcResult(future, invocation); + asyncRpcResult.complete(appResponse); + return asyncRpcResult; } } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java index 344548829044..53ad128efa76 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Filter.java @@ -47,6 +47,19 @@ public interface Filter { */ Result invoke(Invoker invoker, Invocation invocation) throws RpcException; + /** + * Filter itself should only be response for passing invocation, all callbacks has been placed into {@link Listener} + * + * @param appResponse + * @param invoker + * @param invocation + * @return + */ + @Deprecated + default Result onResponse(Result appResponse, Invoker invoker, Invocation invocation) { + return appResponse; + } + interface Listener { void onResponse(Result appResponse, Invoker invoker, Invocation invocation); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java index 1ecd9dae7715..9c0c1ab50ca8 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java @@ -19,7 +19,8 @@ import java.io.Serializable; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; +import java.util.concurrent.CompletionStage; +import java.util.concurrent.Future; import java.util.function.Function; @@ -30,7 +31,7 @@ * @see org.apache.dubbo.rpc.Invoker#invoke(Invocation) * @see AppResponse */ -public interface Result extends Serializable { +public interface Result extends CompletionStage, Future, Serializable { /** * Get invoke result. @@ -110,10 +111,17 @@ public interface Result extends Serializable { void setAttachment(String key, String value); - Result thenApplyWithContext(Function fn); - - CompletableFuture thenApply(Function fn); + /** + * Returns the specified {@code valueIfAbsent} when not complete, or + * returns the result value or throws an exception when complete. + * + * @see CompletableFuture#getNow(Object) + */ + Result getNow(Result valueIfAbsent); - Result get() throws InterruptedException, ExecutionException; + Result thenApplyWithContext(Function fn); + default CompletableFuture completionFuture() { + return toCompletableFuture(); + } } \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java index 2106a4e0da8e..0ca8cede50d3 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/ProtocolFilterWrapper.java @@ -90,6 +90,8 @@ public Result invoke(Invocation invocation) throws RpcException { if (listener != null) { listener.onResponse(r, invoker, invocation); } + } else { + filter.onResponse(r, invoker, invocation); } return r; }); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java index aa813e1d1a5e..fe42fb2c6be7 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/AbstractProxyInvoker.java @@ -84,7 +84,8 @@ public Result invoke(Invocation invocation) throws RpcException { try { Object value = doInvoke(proxy, invocation.getMethodName(), invocation.getParameterTypes(), invocation.getArguments()); CompletableFuture future = wrapWithFuture(value, invocation); - CompletableFuture appResponseFuture = future.handle((obj, t) -> { + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation); + future.whenComplete((obj, t) -> { AppResponse result = new AppResponse(); if (t != null) { if (t instanceof CompletionException) { @@ -95,9 +96,9 @@ public Result invoke(Invocation invocation) throws RpcException { } else { result.setValue(obj); } - return result; + asyncRpcResult.complete(result); }); - return new AsyncRpcResult(appResponseFuture, invocation); + return asyncRpcResult; } catch (InvocationTargetException e) { if (RpcContext.getContext().isAsyncStarted() && !RpcContext.getContext().stopAsync()) { logger.error("Provider async started, but got an exception from the original method, cannot write the exception back to consumer because an async result may have returned the new thread.", e); diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java index 49af0c0951ee..bc9c1320372e 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/ExceptionFilterTest.java @@ -28,12 +28,11 @@ import org.apache.dubbo.rpc.support.LocalException; import com.alibaba.com.caucho.hessian.HessianException; + import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.mockito.Mockito; -import java.util.concurrent.CompletableFuture; - import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.BDDMockito.given; @@ -121,7 +120,7 @@ public void testConvertToRunTimeException() throws Exception { AppResponse mockRpcResult = new AppResponse(); mockRpcResult.setException(new HessianException("hessian")); - Result mockAsyncResult = new AsyncRpcResult(CompletableFuture.completedFuture(mockRpcResult), invocation); + Result mockAsyncResult = AsyncRpcResult.newDefaultAsyncResult(mockRpcResult, invocation); Invoker invoker = mock(Invoker.class); diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java index 469632b9ec37..aa3927971a37 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/filter/GenericImplFilterTest.java @@ -36,7 +36,6 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.CompletableFuture; import static org.mockito.Mockito.any; import static org.mockito.Mockito.when; @@ -61,7 +60,7 @@ public void testInvoke() throws Exception { person.put("age", 10); AppResponse mockRpcResult = new AppResponse(person); - when(invoker.invoke(any(Invocation.class))).thenReturn(new AsyncRpcResult(CompletableFuture.completedFuture(mockRpcResult), invocation)); + when(invoker.invoke(any(Invocation.class))).thenReturn(AsyncRpcResult.newDefaultAsyncResult(mockRpcResult, invocation)); when(invoker.getUrl()).thenReturn(url); when(invoker.getInterface()).thenReturn(DemoService.class); @@ -84,7 +83,7 @@ public void testInvokeWithException() throws Exception { Invoker invoker = Mockito.mock(Invoker.class); AppResponse mockRpcResult = new AppResponse(new GenericException(new RuntimeException("failed"))); - when(invoker.invoke(any(Invocation.class))).thenReturn(new AsyncRpcResult(CompletableFuture.completedFuture(mockRpcResult), invocation)); + when(invoker.invoke(any(Invocation.class))).thenReturn(AsyncRpcResult.newDefaultAsyncResult(mockRpcResult, invocation)); when(invoker.getUrl()).thenReturn(url); when(invoker.getInterface()).thenReturn(DemoService.class); diff --git a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java index 1b74e6bc41b4..57f1f1e6cc54 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/test/java/org/apache/dubbo/rpc/support/MyInvoker.java @@ -24,8 +24,6 @@ import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcException; -import java.util.concurrent.CompletableFuture; - /** * MockInvoker.java */ @@ -68,7 +66,7 @@ public Result invoke(Invocation invocation) throws RpcException { result.setException(new RuntimeException("mocked exception")); } - return new AsyncRpcResult(CompletableFuture.completedFuture(result), invocation); + return AsyncRpcResult.newDefaultAsyncResult(result, invocation); } @Override diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java index 5a22127d3ef2..17b2cca56713 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java @@ -66,8 +66,16 @@ protected Result doInvoke(Invocation invocation) throws Throwable { currentClient.send(inv, getUrl().getMethodParameter(invocation.getMethodName(), Constants.SENT_KEY, false)); return AsyncRpcResult.newDefaultAsyncResult(invocation); } else { - CompletableFuture appResponseFuture = currentClient.request(inv).thenApply(obj -> (AppResponse) obj); - return new AsyncRpcResult(appResponseFuture, inv); + CompletableFuture responseFuture = currentClient.request(inv); + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(inv); + responseFuture.whenComplete((appResponse, t) -> { + if (t != null) { + asyncRpcResult.completeExceptionally(t); + } else { + asyncRpcResult.complete((AppResponse) appResponse); + } + }); + return asyncRpcResult; } } catch (RpcException e) { throw e; diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java index d8513a318060..0f77d65d7a18 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvoker.java @@ -87,9 +87,17 @@ protected Result doInvoke(final Invocation invocation) throws Throwable { RpcContext.getContext().setFuture(null); return AsyncRpcResult.newDefaultAsyncResult(invocation); } else { - CompletableFuture appResponseFuture = currentClient.request(inv, timeout).thenApply(obj -> (AppResponse) obj); - RpcContext.getContext().setFuture(new FutureAdapter(appResponseFuture)); - return new AsyncRpcResult(appResponseFuture, inv); + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(inv); + CompletableFuture responseFuture = currentClient.request(inv, timeout); + responseFuture.whenComplete((obj, t) -> { + if (t != null) { + asyncRpcResult.completeExceptionally(t); + } else { + asyncRpcResult.complete((AppResponse) obj); + } + }); + RpcContext.getContext().setFuture(new FutureAdapter(asyncRpcResult)); + return asyncRpcResult; } } catch (TimeoutException e) { throw new RpcException(RpcException.TIMEOUT_EXCEPTION, "Invoke remote method timeout. method: " + invocation.getMethodName() + ", provider: " + getUrl() + ", cause: " + e.getMessage(), e); diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java index 926a940cd5d5..15b0bd2e0f39 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java @@ -125,7 +125,7 @@ public CompletableFuture reply(ExchangeChannel channel, Object message) } RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress()); Result result = invoker.invoke(inv); - return result.thenApply(Function.identity()); + return result.completionFuture().thenApply(Function.identity()); } @Override diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java index 9fc47f6f9c9d..d00c5fa3f4a7 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.rpc.protocol.dubbo; -import org.apache.dubbo.rpc.Result; +import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.RpcException; import java.util.concurrent.CompletableFuture; @@ -30,21 +30,21 @@ */ public class FutureAdapter extends CompletableFuture { - private CompletableFuture resultFuture; + private CompletableFuture resultFuture; - public FutureAdapter(CompletableFuture future) { + public FutureAdapter(CompletableFuture future) { this.resultFuture = future; - future.whenComplete((result, t) -> { + future.whenComplete((appResponse, t) -> { if (t != null) { if (t instanceof CompletionException) { t = t.getCause(); } this.completeExceptionally(t); } else { - if (result.hasException()) { - this.completeExceptionally(result.getException()); + if (appResponse.hasException()) { + this.completeExceptionally(appResponse.getException()); } else { - this.complete((V)result.getValue()); + this.complete((V) appResponse.getValue()); } } }); diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java index e02fac3a176e..6eb3c6a43787 100644 --- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java +++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftInvoker.java @@ -22,7 +22,6 @@ import org.apache.dubbo.remoting.RemotingException; import org.apache.dubbo.remoting.TimeoutException; import org.apache.dubbo.remoting.exchange.ExchangeClient; -import org.apache.dubbo.rpc.AppResponse; import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -89,9 +88,11 @@ protected Result doInvoke(Invocation invocation) throws Throwable { int timeout = getUrl().getMethodParameter( methodName, Constants.TIMEOUT_KEY, Constants.DEFAULT_TIMEOUT); - CompletableFuture appResponseFuture = currentClient.request(inv, timeout).thenApply(obj -> (AppResponse) obj); - RpcContext.getContext().setFuture(new FutureAdapter(appResponseFuture)); - return new AsyncRpcResult(appResponseFuture, invocation); + AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation); + CompletableFuture responseFuture = currentClient.request(inv, timeout); + asyncRpcResult.subscribeTo(responseFuture); + RpcContext.getContext().setFuture(new FutureAdapter(asyncRpcResult)); + return asyncRpcResult; } catch (TimeoutException e) { throw new RpcException(RpcException.TIMEOUT_EXCEPTION, e.getMessage(), e); } catch (RemotingException e) { From 670690ec5bef204efa9641432376552e6d47ca50 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 24 Apr 2019 11:18:44 +0800 Subject: [PATCH 05/26] get CompletableFuture before thenApply --- .../org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java index 61c13ccce651..e80d61c82ae6 100644 --- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java +++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java @@ -87,7 +87,7 @@ public CompletableFuture reply(ExchangeChannel channel, Object msg) thro RpcContext.getContext().setRemoteAddress(channel.getRemoteAddress()); Result result = exporter.getInvoker().invoke(inv); - return result.thenApply(Function.identity()); + return result.completionFuture().thenApply(Function.identity()); } throw new RemotingException(channel, From 0d0c9911f3bd0ea08c18ee63e177ffdd742db924 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 24 Apr 2019 14:52:29 +0800 Subject: [PATCH 06/26] rename property to avoid possible confusion --- .../apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java index d00c5fa3f4a7..03954d1b3452 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/FutureAdapter.java @@ -30,10 +30,10 @@ */ public class FutureAdapter extends CompletableFuture { - private CompletableFuture resultFuture; + private CompletableFuture appResponseFuture; public FutureAdapter(CompletableFuture future) { - this.resultFuture = future; + this.appResponseFuture = future; future.whenComplete((appResponse, t) -> { if (t != null) { if (t instanceof CompletionException) { @@ -53,12 +53,12 @@ public FutureAdapter(CompletableFuture future) { // TODO figure out the meaning of cancel in DefaultFuture. @Override public boolean cancel(boolean mayInterruptIfRunning) { - return resultFuture.cancel(mayInterruptIfRunning); + return appResponseFuture.cancel(mayInterruptIfRunning); } @Override public boolean isCancelled() { - return resultFuture.isCancelled(); + return appResponseFuture.isCancelled(); } @Override From db962a11da6736cbfe403ce5796353d4cbfb0be1 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 24 Apr 2019 15:20:01 +0800 Subject: [PATCH 07/26] add comment --- .../java/org/apache/dubbo/rpc/AsyncRpcResult.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java index e15053ac7fa1..2cb6cd9b23bd 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java @@ -24,6 +24,20 @@ import java.util.concurrent.CompletionException; import java.util.function.Function; +/** + * This class represents an unfinished RPC call, it will hold some context information for this call, for example RpcContext and Invocation, + * so that when the call finishes and the result returns, it can guarantee all the contexts being recovered as the same as when the call was made + * before any callback is invoked. + *

    + * TODO if it's reasonable or even right to keep a reference to Invocation? + *

    + * As {@link Result} implements CompletionStage, {@link AsyncRpcResult} allows you to easily build a async filter chain whose status will be + * driven entirely by the state of the underlying RPC call. + *

    + * AsyncRpcResult does not contain any concrete value (except the underlying value bring by CompletableFuture), consider it as a status transfer node. + * In this case, {@link #getValue()} and {@link #getException()} are all inherited from {@link Result} interface, implementing them are mainly + * for compatibility consideration. Because many legacy {@link Filter} implementation are most possibly to call getValue directly. + */ public class AsyncRpcResult extends AbstractResult { private static final Logger logger = LoggerFactory.getLogger(AsyncRpcResult.class); From 597141039b8ba13ba6dcac493090c1516212ffa9 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 24 Apr 2019 15:22:35 +0800 Subject: [PATCH 08/26] add comment --- .../src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java index 2cb6cd9b23bd..9546e2a39cee 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/AsyncRpcResult.java @@ -35,7 +35,7 @@ * driven entirely by the state of the underlying RPC call. *

    * AsyncRpcResult does not contain any concrete value (except the underlying value bring by CompletableFuture), consider it as a status transfer node. - * In this case, {@link #getValue()} and {@link #getException()} are all inherited from {@link Result} interface, implementing them are mainly + * {@link #getValue()} and {@link #getException()} are all inherited from {@link Result} interface, implementing them are mainly * for compatibility consideration. Because many legacy {@link Filter} implementation are most possibly to call getValue directly. */ public class AsyncRpcResult extends AbstractResult { From d9676b877bd27d8acc7da8966f40558f44d907f4 Mon Sep 17 00:00:00 2001 From: Huxing Zhang Date: Sun, 20 May 2018 14:37:53 +0800 Subject: [PATCH 09/26] add comment --- .../src/main/java/org/apache/dubbo/rpc/Result.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java index 9c0c1ab50ca8..7ad22c64cbbc 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java @@ -25,7 +25,14 @@ /** - * RPC invoke result. (API, Prototype, NonThreadSafe) + * (API, Prototype, NonThreadSafe) + * + * An RPC {@link Result}. + * + * Known implementations are: + * 1. {@link AsyncRpcResult}, it's a {@link CompletionStage} whose underlying value signifies the return value of an RPC call. + * 2. {@link AppResponse}, it inevitably inherits {@link CompletionStage} and {@link Future}, but you should never treat AppResponse as a type of Future, + * instead, it is a normal concrete type. * * @serial Don't change the class name and package name. * @see org.apache.dubbo.rpc.Invoker#invoke(Invocation) From 5c90c8fecd2d1587d9309d195cfaaaf165d7b116 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Fri, 26 Apr 2019 14:58:34 +0800 Subject: [PATCH 10/26] add comment --- .../src/main/java/org/apache/dubbo/rpc/Result.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java index 7ad22c64cbbc..1f3a51383194 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/Result.java @@ -126,6 +126,15 @@ public interface Result extends CompletionStage, Future, Seriali */ Result getNow(Result valueIfAbsent); + /** + * Add a callback which can be triggered when the RPC call finishes. + *

    + * Just as the method name implies, this method will guarantee the callback being triggered under the same context as when the call was started, + * see implementation in {@link AsyncRpcResult#thenApplyWithContext(Function)} + * + * @param fn + * @return + */ Result thenApplyWithContext(Function fn); default CompletableFuture completionFuture() { From 93688fde2cc19957a6b407301d3eb0098f11d22e Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 8 May 2019 17:23:50 +0800 Subject: [PATCH 11/26] resolve conflicts when merging async from 3.x --- .../main/java/org/apache/dubbo/rpc/filter/GenericFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java index 527d5d5ff89e..ea1e7409a779 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java @@ -176,8 +176,8 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation inv) { UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512); ExtensionLoader.getExtensionLoader(Serialization.class) .getExtension(Constants.GENERIC_SERIALIZATION_PROTOBUF) - .serialize(null, os).writeObject(result.getValue()); - return new RpcResult(os.toString()); + .serialize(null, os).writeObject(appResponse.getValue()); + appResponse.setValue(os.toString()); } catch (IOException e) { throw new RpcException("Generic serialization [" + Constants.GENERIC_SERIALIZATION_PROTOBUF + From 82ffe21c9985e3bf81d4f6c2e7256dab26b0cc2e Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 8 May 2019 17:30:27 +0800 Subject: [PATCH 12/26] keep dubbo-demo unchanged --- .../demo/consumer/comp/DemoServiceComponent.java | 7 ------- .../apache/dubbo/demo/provider/DemoServiceImpl.java | 7 ------- .../apache/dubbo/demo/provider/DemoServiceImpl.java | 7 ------- .../main/java/org/apache/dubbo/demo/DemoService.java | 3 --- .../org/apache/dubbo/demo/consumer/Application.java | 11 +++-------- .../src/main/resources/spring/dubbo-consumer.xml | 2 +- .../apache/dubbo/demo/provider/DemoServiceImpl.java | 12 ------------ 7 files changed, 4 insertions(+), 45 deletions(-) diff --git a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java index db6b7559a769..4305ed6c05f6 100644 --- a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java +++ b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-consumer/src/main/java/org/apache/dubbo/demo/consumer/comp/DemoServiceComponent.java @@ -24,8 +24,6 @@ import org.springframework.stereotype.Component; -import java.util.concurrent.CompletableFuture; - @Component("demoServiceComponent") public class DemoServiceComponent implements DemoService { @Reference @@ -35,9 +33,4 @@ public class DemoServiceComponent implements DemoService { public String sayHello(String name) { return demoService.sayHello(name); } - - @Override - public CompletableFuture sayHelloAsync(String name) { - return null; - } } diff --git a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java index 137fa23ead6a..cb06537ae012 100644 --- a/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-annotation/dubbo-demo-annotation-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java @@ -25,8 +25,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.CompletableFuture; - @Service public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @@ -37,9 +35,4 @@ public String sayHello(String name) { return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } - @Override - public CompletableFuture sayHelloAsync(String name) { - return null; - } - } diff --git a/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java b/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java index 2f13a5c6714e..5e2ef2350d25 100644 --- a/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-api/dubbo-demo-api-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java @@ -22,8 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.CompletableFuture; - public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @@ -33,9 +31,4 @@ public String sayHello(String name) { return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } - @Override - public CompletableFuture sayHelloAsync(String name) { - return null; - } - } diff --git a/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java b/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java index bd9c9287de75..1172c9be0fc3 100644 --- a/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java +++ b/dubbo-demo/dubbo-demo-interface/src/main/java/org/apache/dubbo/demo/DemoService.java @@ -16,11 +16,8 @@ */ package org.apache.dubbo.demo; -import java.util.concurrent.CompletableFuture; - public interface DemoService { String sayHello(String name); - CompletableFuture sayHelloAsync(String name); } \ No newline at end of file diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java index ad34442a4364..90ed7c0b6a6b 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/java/org/apache/dubbo/demo/consumer/Application.java @@ -20,21 +20,16 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; -import java.util.concurrent.CompletableFuture; - public class Application { /** * In order to make sure multicast registry works, need to specify '-Djava.net.preferIPv4Stack=true' before * launch the application */ - public static void main(String[] args) throws Exception { + public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring/dubbo-consumer.xml"); context.start(); DemoService demoService = context.getBean("demoService", DemoService.class); -// String hello = demoService.sayHello("world"); - CompletableFuture helloFuture = demoService.sayHelloAsync("world"); -// System.out.println("result: " + hello); - System.out.println("result: " + helloFuture.get()); - System.in.read(); + String hello = demoService.sayHello("world"); + System.out.println("result: " + hello); } } diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml index 286b24b3f15e..6b5efc32f00b 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-consumer/src/main/resources/spring/dubbo-consumer.xml @@ -27,6 +27,6 @@ - + diff --git a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java index e95caa60444a..d0d315c9b4e6 100644 --- a/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java +++ b/dubbo-demo/dubbo-demo-xml/dubbo-demo-xml-provider/src/main/java/org/apache/dubbo/demo/provider/DemoServiceImpl.java @@ -22,8 +22,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.concurrent.CompletableFuture; - public class DemoServiceImpl implements DemoService { private static final Logger logger = LoggerFactory.getLogger(DemoServiceImpl.class); @@ -33,14 +31,4 @@ public String sayHello(String name) { return "Hello " + name + ", response from provider: " + RpcContext.getContext().getLocalAddress(); } - @Override - public CompletableFuture sayHelloAsync(String name) { - try { - Thread.sleep(10000); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return CompletableFuture.completedFuture("future return value!"); - } - } From 2e9e367d4a0df6d4833a285baeefea66e2295d4c Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Mon, 13 May 2019 16:37:44 +0800 Subject: [PATCH 13/26] delete PropertiesConfigurationTest, does not exit in master branch before. --- .../config/PropertiesConfigurationTest.java | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java deleted file mode 100644 index 30b81f0a67f8..000000000000 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/PropertiesConfigurationTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.dubbo.common.config; - - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class PropertiesConfigurationTest { - - @Test - public void testOrderPropertiesProviders() { - PropertiesConfiguration configuration = new PropertiesConfiguration("test", null); - Assertions.assertTrue(configuration.getInternalProperty("testKey").equals("999")); - } - -} From de320bae1df53d57b0262ce54e2ca636b8950f74 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Tue, 14 May 2019 12:49:53 +0800 Subject: [PATCH 14/26] merge master to resolve conflicts --- .../dubbo/common/constants/RpcConstants.java | 2 + .../dubbo/cache/filter/CacheFilter.java | 3 +- .../dubbo/monitor/support/MonitorFilter.java | 30 +++++++++----- dubbo-registry/dubbo-registry-sofa/pom.xml | 2 +- .../dubbo/rpc/filter/ActiveLimitFilter.java | 16 ++++---- .../dubbo/rpc/filter/CompatibleFilter.java | 5 ++- .../rpc/filter/ConsumerContextFilter.java | 5 ++- .../dubbo/rpc/filter/ContextFilter.java | 33 ++++++++++----- .../apache/dubbo/rpc/filter/EchoFilter.java | 8 ++-- .../dubbo/rpc/filter/ExceptionFilter.java | 4 +- .../dubbo/rpc/filter/ExecuteLimitFilter.java | 9 ++-- .../dubbo/rpc/filter/GenericFilter.java | 41 +++++++++++-------- .../dubbo/rpc/filter/GenericImplFilter.java | 24 ++++++----- .../dubbo/rpc/filter/TimeoutFilter.java | 4 +- .../dubbo/rpc/protocol/AbstractInvoker.java | 2 - .../apache/dubbo/rpc/support/RpcUtils.java | 8 ++-- .../protocol/dubbo/filter/FutureFilter.java | 8 ++-- dubbo-rpc/dubbo-rpc-native-thrift/pom.xml | 2 +- dubbo-rpc/dubbo-rpc-rest/pom.xml | 24 +++++------ 19 files changed, 137 insertions(+), 93 deletions(-) diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RpcConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RpcConstants.java index 9e7302ff0ad9..ce204728611f 100644 --- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RpcConstants.java +++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/RpcConstants.java @@ -109,6 +109,8 @@ public interface RpcConstants { String $INVOKE = "$invoke"; + String $INVOKE_ASYNC = "$invokeAsync"; + String $ECHO = "$echo"; String RETURN_PREFIX = "return "; diff --git a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java index 2f207b83b08c..56ad1f0ec5fd 100644 --- a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java +++ b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java @@ -19,6 +19,7 @@ import org.apache.dubbo.cache.Cache; import org.apache.dubbo.cache.CacheFactory; import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.ConfigUtils; import org.apache.dubbo.common.utils.StringUtils; @@ -61,7 +62,7 @@ * @see org.apache.dubbo.cache.support.expiring.ExpiringCache * */ -@Activate(group = {Constants.CONSUMER, Constants.PROVIDER}, value = Constants.CACHE_KEY) +@Activate(group = {CommonConstants.CONSUMER, CommonConstants.PROVIDER}, value = Constants.CACHE_KEY) public class CacheFilter implements Filter { private CacheFactory cacheFactory; diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java index 5358719e75ec..6ba5dfe84b4f 100644 --- a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java +++ b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java @@ -37,10 +37,20 @@ import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicInteger; +import static org.apache.dubbo.common.constants.CommonConstants.APPLICATION_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER_SIDE; +import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR; +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER; +import static org.apache.dubbo.common.constants.CommonConstants.SIDE_KEY; +import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.INPUT_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.OUTPUT_KEY; /** * MonitorFilter. (SPI, Singleton, ThreadSafe) */ -@Activate(group = {Constants.PROVIDER, Constants.CONSUMER}) +@Activate(group = {PROVIDER, CONSUMER}) public class MonitorFilter extends ListenableFilter { private static final Logger logger = LoggerFactory.getLogger(MonitorFilter.class); @@ -149,15 +159,15 @@ private URL createStatisticsUrl(Invoker invoker, Invocation invocation, Resul // ---- service statistics ---- long elapsed = System.currentTimeMillis() - start; // invocation cost int concurrent = getConcurrent(invoker, invocation).get(); // current concurrent count - String application = invoker.getUrl().getParameter(Constants.APPLICATION_KEY); + String application = invoker.getUrl().getParameter(APPLICATION_KEY); String service = invoker.getInterface().getName(); // service name String method = RpcUtils.getMethodName(invocation); // method name - String group = invoker.getUrl().getParameter(Constants.GROUP_KEY); - String version = invoker.getUrl().getParameter(Constants.VERSION_KEY); + String group = invoker.getUrl().getParameter(GROUP_KEY); + String version = invoker.getUrl().getParameter(VERSION_KEY); int localPort; String remoteKey, remoteValue; - if (Constants.CONSUMER_SIDE.equals(invoker.getUrl().getParameter(Constants.SIDE_KEY))) { + if (CONSUMER_SIDE.equals(invoker.getUrl().getParameter(SIDE_KEY))) { // ---- for service consumer ---- localPort = 0; remoteKey = MonitorService.PROVIDER; @@ -169,14 +179,14 @@ private URL createStatisticsUrl(Invoker invoker, Invocation invocation, Resul remoteValue = remoteHost; } String input = "", output = ""; - if (invocation.getAttachment(Constants.INPUT_KEY) != null) { - input = invocation.getAttachment(Constants.INPUT_KEY); + if (invocation.getAttachment(INPUT_KEY) != null) { + input = invocation.getAttachment(INPUT_KEY); } - if (result != null && result.getAttachment(Constants.OUTPUT_KEY) != null) { - output = result.getAttachment(Constants.OUTPUT_KEY); + if (result != null && result.getAttachment(OUTPUT_KEY) != null) { + output = result.getAttachment(OUTPUT_KEY); } - return new URL(Constants.COUNT_PROTOCOL, NetUtils.getLocalHost(), localPort, service + Constants.PATH_SEPARATOR + method, MonitorService.APPLICATION, application, MonitorService.INTERFACE, service, MonitorService.METHOD, method, remoteKey, remoteValue, error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1", MonitorService.ELAPSED, String.valueOf(elapsed), MonitorService.CONCURRENT, String.valueOf(concurrent), Constants.INPUT_KEY, input, Constants.OUTPUT_KEY, output, Constants.GROUP_KEY, group, Constants.VERSION_KEY, version); + return new URL(Constants.COUNT_PROTOCOL, NetUtils.getLocalHost(), localPort, service + PATH_SEPARATOR + method, MonitorService.APPLICATION, application, MonitorService.INTERFACE, service, MonitorService.METHOD, method, remoteKey, remoteValue, error ? MonitorService.FAILURE : MonitorService.SUCCESS, "1", MonitorService.ELAPSED, String.valueOf(elapsed), MonitorService.CONCURRENT, String.valueOf(concurrent), INPUT_KEY, input, OUTPUT_KEY, output, GROUP_KEY, group, VERSION_KEY, version); } } diff --git a/dubbo-registry/dubbo-registry-sofa/pom.xml b/dubbo-registry/dubbo-registry-sofa/pom.xml index 7a2415fc216b..9faccea3868e 100644 --- a/dubbo-registry/dubbo-registry-sofa/pom.xml +++ b/dubbo-registry/dubbo-registry-sofa/pom.xml @@ -32,7 +32,7 @@ 2.1 -Dnetwork_interface_denylist=docker0 - + org.apache.dubbo diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java index 1fd0a8b9b33c..4117002cb24e 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ActiveLimitFilter.java @@ -16,7 +16,6 @@ */ package org.apache.dubbo.rpc.filter; -import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.StringUtils; @@ -28,8 +27,11 @@ import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcStatus; +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER; +import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.ACTIVES_KEY; + /** - * * ActiveLimitFilter restrict the concurrent client invocation for a service or service's method from client side. * To use active limit filter, configured url with actives and provide valid >0 integer value. *

    @@ -41,7 +43,7 @@
      *
      * @see Filter
      */
    -@Activate(group = Constants.CONSUMER, value = Constants.ACTIVES_KEY)
    +@Activate(group = CONSUMER, value = ACTIVES_KEY)
     public class ActiveLimitFilter extends ListenableFilter {
     
         private static final String ACTIVELIMIT_FILTER_START_TIME = "activelimit_filter_start_time";
    @@ -54,10 +56,10 @@ public ActiveLimitFilter() {
         public Result invoke(Invoker invoker, Invocation invocation) throws RpcException {
             URL url = invoker.getUrl();
             String methodName = invocation.getMethodName();
    -        int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
    +        int max = invoker.getUrl().getMethodParameter(methodName, ACTIVES_KEY, 0);
             RpcStatus rpcStatus = RpcStatus.getStatus(invoker.getUrl(), invocation.getMethodName());
             if (!RpcStatus.beginCount(url, methodName, max)) {
    -            long timeout = invoker.getUrl().getMethodParameter(invocation.getMethodName(), Constants.TIMEOUT_KEY, 0);
    +            long timeout = invoker.getUrl().getMethodParameter(invocation.getMethodName(), TIMEOUT_KEY, 0);
                 long start = System.currentTimeMillis();
                 long remain = timeout;
                 synchronized (rpcStatus) {
    @@ -86,7 +88,7 @@ static class ActiveLimitListener implements Listener {
             public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) {
                 String methodName = invocation.getMethodName();
                 URL url = invoker.getUrl();
    -            int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
    +            int max = invoker.getUrl().getMethodParameter(methodName, ACTIVES_KEY, 0);
     
                 RpcStatus.endCount(url, methodName, getElapsed(invocation), true);
                 notifyFinish(RpcStatus.getStatus(url, methodName), max);
    @@ -96,7 +98,7 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation invoca
             public void onError(Throwable t, Invoker invoker, Invocation invocation) {
                 String methodName = invocation.getMethodName();
                 URL url = invoker.getUrl();
    -            int max = invoker.getUrl().getMethodParameter(methodName, Constants.ACTIVES_KEY, 0);
    +            int max = invoker.getUrl().getMethodParameter(methodName, ACTIVES_KEY, 0);
     
                 RpcStatus.endCount(url, methodName, getElapsed(invocation), false);
                 notifyFinish(RpcStatus.getStatus(url, methodName), max);
    diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
    index 2eb67b4df29a..895c008f664d 100644
    --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
    +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java
    @@ -16,7 +16,6 @@
      */
     package org.apache.dubbo.rpc.filter;
     
    -import org.apache.dubbo.common.Constants;
     import org.apache.dubbo.common.logger.Logger;
     import org.apache.dubbo.common.logger.LoggerFactory;
     import org.apache.dubbo.common.utils.CompatibleTypeUtils;
    @@ -31,6 +30,8 @@
     import java.lang.reflect.Method;
     import java.lang.reflect.Type;
     
    +import static org.apache.dubbo.common.constants.RemotingConstants.SERIALIZATION_KEY;
    +
     /**
      * CompatibleFilter make the remote method's return value compatible to invoker's version of object.
      * To make return object compatible it does
    @@ -68,7 +69,7 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation invoca
                             Method method = invoker.getInterface().getMethod(invocation.getMethodName(), invocation.getParameterTypes());
                             Class type = method.getReturnType();
                             Object newValue;
    -                        String serialization = invoker.getUrl().getParameter(Constants.SERIALIZATION_KEY);
    +                        String serialization = invoker.getUrl().getParameter(SERIALIZATION_KEY);
                             if ("json".equals(serialization) || "fastjson".equals(serialization)) {
                                 // If the serialization key is json or fastjson
                                 Type gtype = method.getGenericReturnType();
    diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
    index 794b6fdd9875..43353f7e7dcc 100644
    --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
    +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ConsumerContextFilter.java
    @@ -16,7 +16,6 @@
      */
     package org.apache.dubbo.rpc.filter;
     
    -import org.apache.dubbo.common.Constants;
     import org.apache.dubbo.common.extension.Activate;
     import org.apache.dubbo.common.utils.NetUtils;
     import org.apache.dubbo.rpc.Invocation;
    @@ -27,6 +26,8 @@
     import org.apache.dubbo.rpc.RpcException;
     import org.apache.dubbo.rpc.RpcInvocation;
     
    +import static org.apache.dubbo.common.constants.CommonConstants.CONSUMER;
    +
     /**
      * ConsumerContextFilter set current RpcContext with invoker,invocation, local host, remote host and port
      * for consumer invoker.It does it to make the requires info available to execution thread's RpcContext.
    @@ -34,7 +35,7 @@
      * @see org.apache.dubbo.rpc.Filter
      * @see RpcContext
      */
    -@Activate(group = Constants.CONSUMER, order = -10000)
    +@Activate(group = CONSUMER, order = -10000)
     public class ConsumerContextFilter extends ListenableFilter {
     
         public ConsumerContextFilter() {
    diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
    index 1a8e40e4b877..099357410bd0 100644
    --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
    +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ContextFilter.java
    @@ -29,7 +29,18 @@
     import java.util.HashMap;
     import java.util.Map;
     
    -import static org.apache.dubbo.common.Constants.REMOTE_APPLICATION_KEY;
    +import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
    +import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
    +import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
    +import static org.apache.dubbo.common.constants.CommonConstants.PROVIDER;
    +import static org.apache.dubbo.common.constants.CommonConstants.REMOTE_APPLICATION_KEY;
    +import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY;
    +import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
    +import static org.apache.dubbo.common.constants.RpcConstants.ASYNC_KEY;
    +import static org.apache.dubbo.common.constants.RpcConstants.DUBBO_VERSION_KEY;
    +import static org.apache.dubbo.common.constants.RpcConstants.FORCE_USE_TAG;
    +import static org.apache.dubbo.common.constants.RpcConstants.TOKEN_KEY;
    +
     
     /**
      * ContextFilter set the provider RpcContext with invoker, invocation, local port it is using and host for
    @@ -37,7 +48,7 @@
      *
      * @see RpcContext
      */
    -@Activate(group = Constants.PROVIDER, order = -10000)
    +@Activate(group = PROVIDER, order = -10000)
     public class ContextFilter extends ListenableFilter {
     
         public ContextFilter() {
    @@ -49,17 +60,17 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept
             Map attachments = invocation.getAttachments();
             if (attachments != null) {
                 attachments = new HashMap<>(attachments);
    -            attachments.remove(Constants.PATH_KEY);
    -            attachments.remove(Constants.INTERFACE_KEY);
    -            attachments.remove(Constants.GROUP_KEY);
    -            attachments.remove(Constants.VERSION_KEY);
    -            attachments.remove(Constants.DUBBO_VERSION_KEY);
    -            attachments.remove(Constants.TOKEN_KEY);
    -            attachments.remove(Constants.TIMEOUT_KEY);
    +            attachments.remove(PATH_KEY);
    +            attachments.remove(INTERFACE_KEY);
    +            attachments.remove(GROUP_KEY);
    +            attachments.remove(VERSION_KEY);
    +            attachments.remove(DUBBO_VERSION_KEY);
    +            attachments.remove(TOKEN_KEY);
    +            attachments.remove(TIMEOUT_KEY);
                 // Remove async property to avoid being passed to the following invoke chain.
    -            attachments.remove(Constants.ASYNC_KEY);
    +            attachments.remove(ASYNC_KEY);
                 attachments.remove(Constants.TAG_KEY);
    -            attachments.remove(Constants.FORCE_USE_TAG);
    +            attachments.remove(FORCE_USE_TAG);
             }
             RpcContext.getContext()
                     .setInvoker(invoker)
    diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java
    index 7e3e5b8dda01..e753f4d78042 100644
    --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java
    +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/EchoFilter.java
    @@ -16,7 +16,7 @@
      */
     package org.apache.dubbo.rpc.filter;
     
    -import org.apache.dubbo.common.Constants;
    +import org.apache.dubbo.common.constants.CommonConstants;
     import org.apache.dubbo.common.extension.Activate;
     import org.apache.dubbo.rpc.AsyncRpcResult;
     import org.apache.dubbo.rpc.Filter;
    @@ -25,15 +25,17 @@
     import org.apache.dubbo.rpc.Result;
     import org.apache.dubbo.rpc.RpcException;
     
    +import static org.apache.dubbo.common.constants.RpcConstants.$ECHO;
    +
     /**
      * Dubbo provided default Echo echo service, which is available for all dubbo provider service interface.
      */
    -@Activate(group = Constants.PROVIDER, order = -110000)
    +@Activate(group = CommonConstants.PROVIDER, order = -110000)
     public class EchoFilter implements Filter {
     
         @Override
         public Result invoke(Invoker invoker, Invocation inv) throws RpcException {
    -        if (inv.getMethodName().equals(Constants.$ECHO) && inv.getArguments() != null && inv.getArguments().length == 1) {
    +        if (inv.getMethodName().equals($ECHO) && inv.getArguments() != null && inv.getArguments().length == 1) {
                 return AsyncRpcResult.newDefaultAsyncResult(inv.getArguments()[0], inv);
             }
             return invoker.invoke(inv);
    diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
    index 4fcf54008e42..8f5411b179c9 100644
    --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
    +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExceptionFilter.java
    @@ -16,7 +16,7 @@
      */
     package org.apache.dubbo.rpc.filter;
     
    -import org.apache.dubbo.common.Constants;
    +import org.apache.dubbo.common.constants.CommonConstants;
     import org.apache.dubbo.common.extension.Activate;
     import org.apache.dubbo.common.logger.Logger;
     import org.apache.dubbo.common.logger.LoggerFactory;
    @@ -43,7 +43,7 @@
      * 
  • Wrap the exception not introduced in API package into RuntimeException. Framework will serialize the outer exception but stringnize its cause in order to avoid of possible serialization problem on client side
  • * */ -@Activate(group = Constants.PROVIDER) +@Activate(group = CommonConstants.PROVIDER) public class ExceptionFilter extends ListenableFilter { public ExceptionFilter() { diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java index 8456a36ff7cb..e76221778764 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/ExecuteLimitFilter.java @@ -16,8 +16,8 @@ */ package org.apache.dubbo.rpc.filter; -import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.URL; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.rpc.Invocation; @@ -27,6 +27,9 @@ import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.RpcStatus; +import static org.apache.dubbo.common.constants.RpcConstants.EXECUTES_KEY; + + /** * * The maximum parallel execution request count per method per service for the provider.If the max configured @@ -34,7 +37,7 @@ * continue the same behaviour un till it is <10. * */ -@Activate(group = Constants.PROVIDER, value = Constants.EXECUTES_KEY) +@Activate(group = CommonConstants.PROVIDER, value = EXECUTES_KEY) public class ExecuteLimitFilter extends ListenableFilter { private static final String EXECUTELIMIT_FILTER_START_TIME = "execugtelimit_filter_start_time"; @@ -47,7 +50,7 @@ public ExecuteLimitFilter() { public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { URL url = invoker.getUrl(); String methodName = invocation.getMethodName(); - int max = url.getMethodParameter(methodName, Constants.EXECUTES_KEY, 0); + int max = url.getMethodParameter(methodName, EXECUTES_KEY, 0); if (!RpcStatus.beginCount(url, methodName, max)) { throw new RpcException("Failed to invoke method " + invocation.getMethodName() + " in provider " + url + ", cause: The service using threads greater than invoker, Invocation inv) throws RpcException { - if ((inv.getMethodName().equals(Constants.$INVOKE) || inv.getMethodName().equals(Constants.$INVOKE_ASYNC)) + if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC)) && inv.getArguments() != null && inv.getArguments().length == 3 && !GenericService.class.isAssignableFrom(invoker.getInterface())) { @@ -67,10 +74,10 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException { if (args == null) { args = new Object[params.length]; } - String generic = inv.getAttachment(Constants.GENERIC_KEY); + String generic = inv.getAttachment(GENERIC_KEY); if (StringUtils.isBlank(generic)) { - generic = RpcContext.getContext().getAttachment(Constants.GENERIC_KEY); + generic = RpcContext.getContext().getAttachment(GENERIC_KEY); } if (StringUtils.isEmpty(generic) @@ -81,7 +88,7 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException { if (byte[].class == args[i].getClass()) { try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) { args[i] = ExtensionLoader.getExtensionLoader(Serialization.class) - .getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA) + .getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA) .deserialize(null, is).readObject(); } catch (Exception e) { throw new RpcException("Deserialize argument [" + (i + 1) + "] failed.", e); @@ -89,7 +96,7 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException { } else { throw new RpcException( "Generic serialization [" + - Constants.GENERIC_SERIALIZATION_NATIVE_JAVA + + GENERIC_SERIALIZATION_NATIVE_JAVA + "] only support message type " + byte[].class + " and your message type is " + @@ -103,7 +110,7 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException { } else { throw new RpcException( "Generic serialization [" + - Constants.GENERIC_SERIALIZATION_BEAN + + GENERIC_SERIALIZATION_BEAN + "] only support message type " + JavaBeanDescriptor.class.getName() + " and your message type is " + @@ -116,7 +123,7 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException { try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) { args[0] = ExtensionLoader.getExtensionLoader(Serialization.class) - .getExtension("" + Constants.GENERIC_SERIALIZATION_PROTOBUF) + .getExtension("" + GENERIC_SERIALIZATION_PROTOBUF) .deserialize(null, is).readObject(method.getParameterTypes()[0]); } catch (Exception e) { throw new RpcException("Deserialize argument failed.", e); @@ -124,7 +131,7 @@ public Result invoke(Invoker invoker, Invocation inv) throws RpcException { } else { throw new RpcException( "Generic serialization [" + - Constants.GENERIC_SERIALIZATION_PROTOBUF + + GENERIC_SERIALIZATION_PROTOBUF + "] only support one" + String.class.getName() + " argument and your message size is " + args.length + " and type is" + @@ -145,14 +152,14 @@ static class GenericListener implements Listener { @Override public void onResponse(Result appResponse, Invoker invoker, Invocation inv) { - if ((inv.getMethodName().equals(Constants.$INVOKE) || inv.getMethodName().equals(Constants.$INVOKE_ASYNC)) + if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC)) && inv.getArguments() != null && inv.getArguments().length == 3 && !GenericService.class.isAssignableFrom(invoker.getInterface())) { - String generic = inv.getAttachment(Constants.GENERIC_KEY); + String generic = inv.getAttachment(GENERIC_KEY); if (StringUtils.isBlank(generic)) { - generic = RpcContext.getContext().getAttachment(Constants.GENERIC_KEY); + generic = RpcContext.getContext().getAttachment(GENERIC_KEY); } if (appResponse.hasException() && !(appResponse.getException() instanceof GenericException)) { @@ -161,12 +168,12 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation inv) { if (ProtocolUtils.isJavaGenericSerialization(generic)) { try { UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512); - ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(Constants.GENERIC_SERIALIZATION_NATIVE_JAVA).serialize(null, os).writeObject(appResponse.getValue()); + ExtensionLoader.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA).serialize(null, os).writeObject(appResponse.getValue()); appResponse.setValue(os.toByteArray()); } catch (IOException e) { throw new RpcException( "Generic serialization [" + - Constants.GENERIC_SERIALIZATION_NATIVE_JAVA + + GENERIC_SERIALIZATION_NATIVE_JAVA + "] serialize result failed.", e); } } else if (ProtocolUtils.isBeanGenericSerialization(generic)) { @@ -175,12 +182,12 @@ public void onResponse(Result appResponse, Invoker invoker, Invocation inv) { try { UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512); ExtensionLoader.getExtensionLoader(Serialization.class) - .getExtension(Constants.GENERIC_SERIALIZATION_PROTOBUF) + .getExtension(GENERIC_SERIALIZATION_PROTOBUF) .serialize(null, os).writeObject(appResponse.getValue()); appResponse.setValue(os.toString()); } catch (IOException e) { throw new RpcException("Generic serialization [" + - Constants.GENERIC_SERIALIZATION_PROTOBUF + + GENERIC_SERIALIZATION_PROTOBUF + "] serialize result failed.", e); } } else { diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java index d6981e9aa55d..b104b2b40319 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java @@ -16,10 +16,10 @@ */ package org.apache.dubbo.rpc.filter; -import org.apache.dubbo.common.Constants; import org.apache.dubbo.common.beanutil.JavaBeanAccessor; import org.apache.dubbo.common.beanutil.JavaBeanDescriptor; import org.apache.dubbo.common.beanutil.JavaBeanSerializeUtil; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -40,10 +40,14 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE_ASYNC; +import static org.apache.dubbo.common.constants.RpcConstants.GENERIC_KEY; + /** * GenericImplInvokerFilter */ -@Activate(group = Constants.CONSUMER, value = Constants.GENERIC_KEY, order = 20000) +@Activate(group = CommonConstants.CONSUMER, value = GENERIC_KEY, order = 20000) public class GenericImplFilter extends ListenableFilter { private static final Logger logger = LoggerFactory.getLogger(GenericImplFilter.class); @@ -56,9 +60,9 @@ public GenericImplFilter() { @Override public Result invoke(Invoker invoker, Invocation invocation) throws RpcException { - String generic = invoker.getUrl().getParameter(Constants.GENERIC_KEY); + String generic = invoker.getUrl().getParameter(GENERIC_KEY); if (ProtocolUtils.isGeneric(generic) - && (!Constants.$INVOKE.equals(invocation.getMethodName()) && !Constants.$INVOKE_ASYNC.equals(invocation.getMethodName())) + && (!$INVOKE.equals(invocation.getMethodName()) && !$INVOKE_ASYNC.equals(invocation.getMethodName())) && invocation instanceof RpcInvocation) { RpcInvocation invocation2 = new RpcInvocation(invocation); String methodName = invocation2.getMethodName(); @@ -81,14 +85,14 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept } if (RpcUtils.isReturnTypeFuture(invocation)) { - invocation2.setMethodName(Constants.$INVOKE_ASYNC); + invocation2.setMethodName($INVOKE_ASYNC); } else { - invocation2.setMethodName(Constants.$INVOKE); + invocation2.setMethodName($INVOKE); } invocation2.setParameterTypes(GENERIC_PARAMETER_TYPES); invocation2.setArguments(new Object[]{methodName, types, args}); return invoker.invoke(invocation2); - } else if ((invocation.getMethodName().equals(Constants.$INVOKE) || invocation.getMethodName().equals(Constants.$INVOKE_ASYNC)) + } else if ((invocation.getMethodName().equals($INVOKE) || invocation.getMethodName().equals($INVOKE_ASYNC)) && invocation.getArguments() != null && invocation.getArguments().length == 3 && ProtocolUtils.isGeneric(generic)) { @@ -110,7 +114,7 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept } invocation.setAttachment( - Constants.GENERIC_KEY, invoker.getUrl().getParameter(Constants.GENERIC_KEY)); + GENERIC_KEY, invoker.getUrl().getParameter(GENERIC_KEY)); } return invoker.invoke(invocation); } @@ -122,11 +126,11 @@ private void error(String generic, String expected, String actual) throws RpcExc static class GenericImplListener implements Listener { @Override public void onResponse(Result appResponse, Invoker invoker, Invocation invocation) { - String generic = invoker.getUrl().getParameter(Constants.GENERIC_KEY); + String generic = invoker.getUrl().getParameter(GENERIC_KEY); String methodName = invocation.getMethodName(); Class[] parameterTypes = invocation.getParameterTypes(); if (ProtocolUtils.isGeneric(generic) - && (!Constants.$INVOKE.equals(invocation.getMethodName()) && !Constants.$INVOKE_ASYNC.equals(invocation.getMethodName())) + && (!$INVOKE.equals(invocation.getMethodName()) && !$INVOKE_ASYNC.equals(invocation.getMethodName())) && invocation instanceof RpcInvocation) { if (!appResponse.hasException()) { Object value = appResponse.getValue(); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java index c51cd3df4275..31b0dc977a82 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/TimeoutFilter.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.rpc.filter; -import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -31,7 +31,7 @@ /** * Log any invocation timeout, but don't stop server from running */ -@Activate(group = Constants.PROVIDER) +@Activate(group = CommonConstants.PROVIDER) public class TimeoutFilter extends ListenableFilter { private static final Logger logger = LoggerFactory.getLogger(TimeoutFilter.class); diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java index 247409ed8d48..58cb4105f864 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java @@ -38,8 +38,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import static org.apache.dubbo.common.constants.RpcConstants.ASYNC_KEY; - /** * AbstractInvoker. */ diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java index 85297812ebd0..4cd13bd17f5a 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java @@ -33,11 +33,11 @@ import java.util.concurrent.atomic.AtomicLong; import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE; -import static org.apache.dubbo.common.constants.RpcConstants.AUTO_ATTACH_INVOCATIONID_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.ID_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE_ASYNC; import static org.apache.dubbo.common.constants.RpcConstants.ASYNC_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.AUTO_ATTACH_INVOCATIONID_KEY; import static org.apache.dubbo.common.constants.RpcConstants.FUTURE_GENERATED_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.FUTURE_RETURNTYPE_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.ID_KEY; import static org.apache.dubbo.common.constants.RpcConstants.RETURN_KEY; /** * RpcUtils @@ -186,7 +186,7 @@ public static InvokeMode getInvokeMode(URL url, Invocation inv) { } public static boolean isGenericAsync(Invocation inv) { - return Constants.$INVOKE_ASYNC.equals(inv.getMethodName()); + return $INVOKE_ASYNC.equals(inv.getMethodName()); } public static boolean isOneway(URL url, Invocation inv) { diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java index 737e73900480..7b1c17c75174 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/FutureFilter.java @@ -16,7 +16,7 @@ */ package org.apache.dubbo.rpc.protocol.dubbo.filter; -import org.apache.dubbo.common.Constants; +import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.extension.Activate; import org.apache.dubbo.common.logger.Logger; import org.apache.dubbo.common.logger.LoggerFactory; @@ -32,10 +32,12 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE; + /** * EventFilter */ -@Activate(group = Constants.CONSUMER) +@Activate(group = CommonConstants.CONSUMER) public class FutureFilter extends ListenableFilter { protected static final Logger logger = LoggerFactory.getLogger(FutureFilter.class); @@ -180,7 +182,7 @@ private ConsumerMethodModel.AsyncMethodInfo getAsyncMethodInfo(Invoker invoke } String methodName = invocation.getMethodName(); - if (methodName.equals(Constants.$INVOKE)) { + if (methodName.equals($INVOKE)) { methodName = (String) invocation.getArguments()[0]; } diff --git a/dubbo-rpc/dubbo-rpc-native-thrift/pom.xml b/dubbo-rpc/dubbo-rpc-native-thrift/pom.xml index 524cd1a706bc..bcc3cf9ec8a2 100644 --- a/dubbo-rpc/dubbo-rpc-native-thrift/pom.xml +++ b/dubbo-rpc/dubbo-rpc-native-thrift/pom.xml @@ -28,7 +28,7 @@ false - + org.apache.dubbo diff --git a/dubbo-rpc/dubbo-rpc-rest/pom.xml b/dubbo-rpc/dubbo-rpc-rest/pom.xml index c1d9e4e727bd..b162030fd8dc 100644 --- a/dubbo-rpc/dubbo-rpc-rest/pom.xml +++ b/dubbo-rpc/dubbo-rpc-rest/pom.xml @@ -91,22 +91,22 @@ io.swagger swagger-annotations - - - javax.ws.rs - jsr311-api - - + + + javax.ws.rs + jsr311-api + + io.swagger swagger-jaxrs - - - javax.ws.rs - jsr311-api - - + + + javax.ws.rs + jsr311-api + + From 09f204773f88c006f0d3668d0c92d5d5fe8ebdc7 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Tue, 14 May 2019 13:06:55 +0800 Subject: [PATCH 15/26] merge master to resolve conflicts --- .../java/org/apache/dubbo/monitor/support/MonitorFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java index 0d8ca6728c70..290f5b4df529 100644 --- a/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java +++ b/dubbo-monitor/dubbo-monitor-api/src/main/java/org/apache/dubbo/monitor/support/MonitorFilter.java @@ -107,7 +107,7 @@ class MonitorListener implements Listener { @Override public void onResponse(Result result, Invoker invoker, Invocation invocation) { - if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) { + if (invoker.getUrl().hasParameter(MONITOR_KEY)) { collect(invoker, invocation, result, RpcContext.getContext().getRemoteHost(), Long.valueOf(invocation.getAttachment(MONITOR_FILTER_START_TIME)), false); getConcurrent(invoker, invocation).decrementAndGet(); // count down } @@ -115,7 +115,7 @@ public void onResponse(Result result, Invoker invoker, Invocation invocation) @Override public void onError(Throwable t, Invoker invoker, Invocation invocation) { - if (invoker.getUrl().hasParameter(Constants.MONITOR_KEY)) { + if (invoker.getUrl().hasParameter(MONITOR_KEY)) { collect(invoker, invocation, null, RpcContext.getContext().getRemoteHost(), Long.valueOf(invocation.getAttachment(MONITOR_FILTER_START_TIME)), true); getConcurrent(invoker, invocation).decrementAndGet(); // count down } From 3194ef7da271c2e778c48d9577eee9ae2b26a7e9 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Tue, 14 May 2019 14:21:37 +0800 Subject: [PATCH 16/26] remove unused imports --- .../org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java index 06cea8c1dc2e..1d047cdccf42 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java @@ -24,9 +24,6 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import static org.apache.dubbo.common.constants.RpcConstants.ASYNC_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.FUTURE_RETURNTYPE_KEY; - /** * InvokerHandler */ From 263485957166392a747c8dcfe3631687786e97be Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Tue, 14 May 2019 15:03:52 +0800 Subject: [PATCH 17/26] remove unused imports --- .../dubbo/rpc/cluster/support/MergeableClusterInvoker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java index fe1608d3c948..593f7033e44f 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java @@ -43,9 +43,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.RpcConstants.MERGER_KEY; /** From 2869f6dd9cadd91a56a4777bbb919c0d2b9a2a55 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 15 May 2019 17:46:50 +0800 Subject: [PATCH 18/26] remove unused imports --- .../apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java index 481fb52de486..8693e508add8 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java @@ -37,12 +37,10 @@ import java.net.InetSocketAddress; import java.util.concurrent.CompletableFuture; -import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.RpcConstants.CALLBACK_SERVICE_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.ASYNC_KEY; import static org.apache.dubbo.common.constants.RpcConstants.TOKEN_KEY; /** From b57d818a33cdc69d815ac4b3421096ad6a12d722 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Thu, 16 May 2019 10:37:11 +0800 Subject: [PATCH 19/26] remove unused imports --- .../java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java | 1 - 1 file changed, 1 deletion(-) diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java index ec2d578ba1d5..5b0c4e5dc367 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java @@ -57,7 +57,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.CopyOnWriteArrayList; import java.util.function.Function; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; From 32a3d07615259118e535d14c2dc074ba7cf20504 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Thu, 16 May 2019 11:26:55 +0800 Subject: [PATCH 20/26] remove unused imports --- .../org/apache/dubbo/rpc/protocol/http/HttpProtocol.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java index a46b12d3e82e..3455b7cf1f2d 100644 --- a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java +++ b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java @@ -17,9 +17,8 @@ package org.apache.dubbo.rpc.protocol.http; import org.apache.dubbo.common.URL; -import org.apache.dubbo.common.constants.RemotingConstants; -import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.common.Version; +import org.apache.dubbo.common.constants.RemotingConstants; import org.apache.dubbo.common.utils.StringUtils; import org.apache.dubbo.remoting.http.HttpBinder; import org.apache.dubbo.remoting.http.HttpHandler; @@ -48,8 +47,8 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; +import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.common.constants.RpcConstants.DUBBO_VERSION_KEY; import static org.apache.dubbo.common.constants.RpcConstants.GENERIC_KEY; From 2b8ce0131f30ee8d3da5fee4a2d7e117b5c6422f Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Thu, 16 May 2019 13:26:15 +0800 Subject: [PATCH 21/26] Fix but, replace AppResponse with AsyncRpcResult --- .../java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java index cf34c8c42d2b..1452313b9cf5 100644 --- a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java +++ b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java @@ -24,7 +24,7 @@ import org.apache.dubbo.common.store.DataStore; import org.apache.dubbo.common.utils.NetUtils; import org.apache.dubbo.monitor.MetricsService; -import org.apache.dubbo.rpc.AppResponse; +import org.apache.dubbo.rpc.AsyncRpcResult; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -235,12 +235,9 @@ public Result invoke(Invocation invocation) throws RpcException { collector.collect(entry.getKey(), entry.getValue(), timestamp); } - AppResponse appResponse = new AppResponse(); - List res = collector.build(); res.addAll(getThreadPoolMessage()); - appResponse.setValue(JSON.toJSONString(res)); - return appResponse; + return AsyncRpcResult.newDefaultAsyncResult(JSON.toJSONString(res), invocation); } @Override From 56953ebb2f8799deaec017497370298d1635e66e Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Thu, 16 May 2019 14:21:35 +0800 Subject: [PATCH 22/26] refactor doRefer in XmlRpcProtocol extension to getFrameProxy --- .../rpc/protocol/xmlrpc/XmlRpcProtocol.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java b/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java index c62bd8c85b89..20cf8c460bac 100644 --- a/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java +++ b/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java @@ -16,16 +16,6 @@ */ package org.apache.dubbo.xml.rpc.protocol.xmlrpc; -import java.io.IOException; -import java.net.SocketTimeoutException; -import java.util.ArrayList; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - import org.apache.dubbo.common.URL; import org.apache.dubbo.remoting.http.HttpBinder; import org.apache.dubbo.remoting.http.HttpHandler; @@ -33,6 +23,7 @@ import org.apache.dubbo.rpc.RpcContext; import org.apache.dubbo.rpc.RpcException; import org.apache.dubbo.rpc.protocol.AbstractProxyProtocol; + import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.XmlRpcRequest; import org.apache.xmlrpc.server.PropertyHandlerMapping; @@ -41,6 +32,15 @@ import org.apache.xmlrpc.webserver.XmlRpcServletServer; import org.springframework.remoting.RemoteAccessException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + public class XmlRpcProtocol extends AbstractProxyProtocol { public static final String ACCESS_CONTROL_ALLOW_ORIGIN_HEADER = "Access-Control-Allow-Origin"; @@ -144,7 +144,7 @@ public void run() { } @SuppressWarnings("unchecked") - protected T doRefer(final Class serviceType, URL url) throws RpcException { + protected T getFrameworkProxy(final Class serviceType, URL url) throws RpcException { XmlRpcProxyFactoryBean xmlRpcProxyFactoryBean = new XmlRpcProxyFactoryBean(); xmlRpcProxyFactoryBean.setServiceUrl(url.setProtocol("http").toIdentityString()); xmlRpcProxyFactoryBean.setServiceInterface(serviceType); From 00aa9927ac3b89889334b2dba9192e213fe68833 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Thu, 16 May 2019 14:58:29 +0800 Subject: [PATCH 23/26] reuse doRefer to reduce backward influences --- .../org/apache/dubbo/rpc/protocol/AbstractProtocol.java | 4 ++-- .../apache/dubbo/rpc/protocol/AbstractProxyProtocol.java | 6 +++--- .../java/org/apache/dubbo/rpc/support/MockProtocol.java | 2 +- .../apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java | 2 +- .../rpc/protocol/dubbo/DubboInvokerAvilableTest.java | 8 ++++---- .../dubbo/rpc/protocol/hessian/HessianProtocol.java | 6 +++--- .../org/apache/dubbo/rpc/protocol/http/HttpProtocol.java | 2 +- .../apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java | 2 +- .../dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java | 2 +- .../dubbo/rpc/protocol/memcached/MemcachedProtocol.java | 2 +- .../dubbo/rpc/protocol/nativethrift/ThriftProtocol.java | 2 +- .../apache/dubbo/rpc/protocol/redis/RedisProtocol.java | 2 +- .../org/apache/dubbo/rpc/protocol/rest/RestProtocol.java | 2 +- .../org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java | 6 +++--- .../apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java | 4 ++-- .../dubbo/rpc/protocol/webservice/WebServiceProtocol.java | 2 +- .../dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java | 2 +- 17 files changed, 28 insertions(+), 28 deletions(-) diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java index c03a063ed0d8..64f005876e2c 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProtocol.java @@ -88,8 +88,8 @@ public void destroy() { @Override public Invoker refer(Class type, URL url) throws RpcException { - return new AsyncToSyncInvoker<>(doRefer(type, url)); + return new AsyncToSyncInvoker<>(protocolBindingRefer(type, url)); } - protected abstract Invoker doRefer(Class type, URL url) throws RpcException; + protected abstract Invoker protocolBindingRefer(Class type, URL url) throws RpcException; } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java index 1271d86972ab..cb3b699f807d 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractProxyProtocol.java @@ -95,8 +95,8 @@ public void unexport() { } @Override - protected Invoker doRefer(final Class type, final URL url) throws RpcException { - final Invoker target = proxyFactory.getInvoker(getFrameworkProxy(type, url), type, url); + protected Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { + final Invoker target = proxyFactory.getInvoker(doRefer(type, url), type, url); Invoker invoker = new AbstractInvoker(type, url) { @Override protected Result doInvoke(Invocation invocation) throws Throwable { @@ -147,6 +147,6 @@ protected int getErrorCode(Throwable e) { protected abstract Runnable doExport(T impl, Class type, URL url) throws RpcException; - protected abstract T getFrameworkProxy(Class type, URL url) throws RpcException; + protected abstract T doRefer(Class type, URL url) throws RpcException; } diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java index ecf7a4524f51..460899681726 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockProtocol.java @@ -38,7 +38,7 @@ public Exporter export(Invoker invoker) throws RpcException { } @Override - public Invoker doRefer(Class type, URL url) throws RpcException { + public Invoker protocolBindingRefer(Class type, URL url) throws RpcException { return new MockInvoker<>(url, type); } } diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java index 5b0c4e5dc367..c42ffd9070be 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/DubboProtocol.java @@ -392,7 +392,7 @@ private void optimizeSerialization(URL url) throws RpcException { } @Override - public Invoker doRefer(Class serviceType, URL url) throws RpcException { + public Invoker protocolBindingRefer(Class serviceType, URL url) throws RpcException { optimizeSerialization(url); // create rpc invoker. diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java index 488b55d61797..fff02a691263 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/test/java/org/apache/dubbo/rpc/protocol/dubbo/DubboInvokerAvilableTest.java @@ -64,7 +64,7 @@ public void test_Normal_available() { URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService"); ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url); - DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url); + DubboInvoker invoker = (DubboInvoker) protocol.protocolBindingRefer(IDemoService.class, url); Assertions.assertEquals(true, invoker.isAvailable()); invoker.destroy(); Assertions.assertEquals(false, invoker.isAvailable()); @@ -75,7 +75,7 @@ public void test_Normal_ChannelReadOnly() throws Exception { URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService"); ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url); - DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url); + DubboInvoker invoker = (DubboInvoker) protocol.protocolBindingRefer(IDemoService.class, url); Assertions.assertEquals(true, invoker.isAvailable()); getClients(invoker)[0].setAttribute(RemotingConstants.CHANNEL_ATTRIBUTE_READONLY_KEY, Boolean.TRUE); @@ -93,7 +93,7 @@ public void test_normal_channel_close_wait_gracefully() throws Exception { Exporter exporter = ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url); Exporter exporter0 = ProtocolUtils.export(new DemoServiceImpl0(), IDemoService.class, url); - DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url); + DubboInvoker invoker = (DubboInvoker) protocol.protocolBindingRefer(IDemoService.class, url); long start = System.currentTimeMillis(); @@ -115,7 +115,7 @@ public void test_NoInvokers() throws Exception { URL url = URL.valueOf("dubbo://127.0.0.1:20883/org.apache.dubbo.rpc.protocol.dubbo.IDemoService?connections=1"); ProtocolUtils.export(new DemoServiceImpl(), IDemoService.class, url); - DubboInvoker invoker = (DubboInvoker) protocol.doRefer(IDemoService.class, url); + DubboInvoker invoker = (DubboInvoker) protocol.protocolBindingRefer(IDemoService.class, url); ExchangeClient[] clients = getClients(invoker); clients[0].close(); diff --git a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java index dac73c68feb9..bc8e4d6c5e71 100644 --- a/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java +++ b/dubbo-rpc/dubbo-rpc-hessian/src/main/java/org/apache/dubbo/rpc/protocol/hessian/HessianProtocol.java @@ -46,12 +46,12 @@ import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_TIMEOUT; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.HESSIAN2_REQUEST_KEY; import static org.apache.dubbo.common.constants.RpcConstants.DEFAULT_HESSIAN2_REQUEST; -import static org.apache.dubbo.common.constants.RpcConstants.HESSIAN_OVERLOAD_METHOD_KEY; import static org.apache.dubbo.common.constants.RpcConstants.DEFAULT_HESSIAN_OVERLOAD_METHOD; import static org.apache.dubbo.common.constants.RpcConstants.DEFAULT_HTTP_CLIENT; import static org.apache.dubbo.common.constants.RpcConstants.GENERIC_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.HESSIAN2_REQUEST_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.HESSIAN_OVERLOAD_METHOD_KEY; /** * http rpc support. */ @@ -102,7 +102,7 @@ public void run() { @Override @SuppressWarnings("unchecked") - protected T getFrameworkProxy(Class serviceType, URL url) throws RpcException { + protected T doRefer(Class serviceType, URL url) throws RpcException { String generic = url.getParameter(GENERIC_KEY); boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class); if (isGeneric) { diff --git a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java index 3455b7cf1f2d..a1a4053308aa 100644 --- a/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java +++ b/dubbo-rpc/dubbo-rpc-http/src/main/java/org/apache/dubbo/rpc/protocol/http/HttpProtocol.java @@ -116,7 +116,7 @@ private HttpInvokerServiceExporter createExporter(T impl, Class type) { @Override @SuppressWarnings("unchecked") - protected T getFrameworkProxy(final Class serviceType, final URL url) throws RpcException { + protected T doRefer(final Class serviceType, final URL url) throws RpcException { final String generic = url.getParameter(GENERIC_KEY); final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class); diff --git a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java index 70e5a19be2de..47a9189e54b4 100644 --- a/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java +++ b/dubbo-rpc/dubbo-rpc-injvm/src/main/java/org/apache/dubbo/rpc/protocol/injvm/InjvmProtocol.java @@ -93,7 +93,7 @@ public Exporter export(Invoker invoker) throws RpcException { } @Override - public Invoker doRefer(Class serviceType, URL url) throws RpcException { + public Invoker protocolBindingRefer(Class serviceType, URL url) throws RpcException { return new InjvmInvoker(serviceType, url, url.getServiceKey(), exporterMap); } diff --git a/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java b/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java index 1708f092fb6c..aaba802cd4ec 100644 --- a/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java +++ b/dubbo-rpc/dubbo-rpc-jsonrpc/src/main/java/org/apache/dubbo/rpc/protocol/jsonrpc/JsonRpcProtocol.java @@ -115,7 +115,7 @@ protected Runnable doExport(T impl, Class type, URL url) throws RpcExcept @SuppressWarnings("unchecked") @Override - protected T getFrameworkProxy(final Class serviceType, URL url) throws RpcException { + protected T doRefer(final Class serviceType, URL url) throws RpcException { JsonProxyFactoryBean jsonProxyFactoryBean = new JsonProxyFactoryBean(); jsonProxyFactoryBean.setServiceUrl(url.setProtocol("http").toIdentityString()); jsonProxyFactoryBean.setServiceInterface(serviceType); diff --git a/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java b/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java index 66e97c3c9650..b056a795ee94 100644 --- a/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java +++ b/dubbo-rpc/dubbo-rpc-memcached/src/main/java/org/apache/dubbo/rpc/protocol/memcached/MemcachedProtocol.java @@ -56,7 +56,7 @@ public Exporter export(final Invoker invoker) throws RpcException { } @Override - public Invoker doRefer(final Class type, final URL url) throws RpcException { + public Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { try { String address = url.getAddress(); String backup = url.getParameter(RemotingConstants.BACKUP_KEY); diff --git a/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java index 16dd3c958255..028d3cf42e25 100644 --- a/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java +++ b/dubbo-rpc/dubbo-rpc-native-thrift/src/main/java/org/apache/dubbo/rpc/protocol/nativethrift/ThriftProtocol.java @@ -69,7 +69,7 @@ protected Runnable doExport(T impl, Class type, URL url) throws RpcExcept } @Override - protected T getFrameworkProxy(Class type, URL url) throws RpcException { + protected T doRefer(Class type, URL url) throws RpcException { return doReferFrameAndCompact(type, url); } diff --git a/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java b/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java index cbe619c6ea3d..b4f400610466 100644 --- a/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java +++ b/dubbo-rpc/dubbo-rpc-redis/src/main/java/org/apache/dubbo/rpc/protocol/redis/RedisProtocol.java @@ -71,7 +71,7 @@ private Serialization getSerialization(URL url) { } @Override - protected Invoker doRefer(final Class type, final URL url) throws RpcException { + protected Invoker protocolBindingRefer(final Class type, final URL url) throws RpcException { try { GenericObjectPoolConfig config = new GenericObjectPoolConfig(); config.setTestOnBorrow(url.getParameter("test.on.borrow", true)); diff --git a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java index 40b8f04a5187..af72a465665d 100644 --- a/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rest/src/main/java/org/apache/dubbo/rpc/protocol/rest/RestProtocol.java @@ -135,7 +135,7 @@ protected Runnable doExport(T impl, Class type, URL url) throws RpcExcept } @Override - protected T getFrameworkProxy(Class serviceType, URL url) throws RpcException { + protected T doRefer(Class serviceType, URL url) throws RpcException { // TODO more configs to add PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); diff --git a/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java b/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java index 8fd653a7a33d..8a7975c8fe5f 100644 --- a/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java @@ -31,11 +31,11 @@ import java.net.SocketTimeoutException; import java.rmi.RemoteException; +import static org.apache.dubbo.common.Version.isRelease263OrHigher; +import static org.apache.dubbo.common.Version.isRelease270OrHigher; import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY; import static org.apache.dubbo.common.constants.RpcConstants.DUBBO_VERSION_KEY; import static org.apache.dubbo.common.constants.RpcConstants.GENERIC_KEY; -import static org.apache.dubbo.common.Version.isRelease263OrHigher; -import static org.apache.dubbo.common.Version.isRelease270OrHigher; /** * RmiProtocol. @@ -72,7 +72,7 @@ public void run() { @Override @SuppressWarnings("unchecked") - protected T getFrameworkProxy(final Class serviceType, final URL url) throws RpcException { + protected T doRefer(final Class serviceType, final URL url) throws RpcException { final RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean(); final String generic = url.getParameter(GENERIC_KEY); final boolean isGeneric = ProtocolUtils.isGeneric(generic) || serviceType.equals(GenericService.class); diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java index d2cbfacad683..1116651b9ee0 100644 --- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java +++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java @@ -46,8 +46,8 @@ import java.util.function.Function; import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.IS_SERVER_KEY; import static org.apache.dubbo.common.constants.RpcConstants.CONNECTIONS_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.IS_SERVER_KEY; /** * @since 2.7.0, use https://github.com/dubbo/dubbo-rpc-native-thrift instead @@ -164,7 +164,7 @@ public void destroy() { } // ~ end of method destroy @Override - protected Invoker doRefer(Class type, URL url) throws RpcException { + protected Invoker protocolBindingRefer(Class type, URL url) throws RpcException { ThriftInvoker invoker = new ThriftInvoker(type, url, getClients(url), invokers); diff --git a/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java b/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java index bc93d993c317..928b01c45ff2 100644 --- a/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java +++ b/dubbo-rpc/dubbo-rpc-webservice/src/main/java/org/apache/dubbo/rpc/protocol/webservice/WebServiceProtocol.java @@ -110,7 +110,7 @@ public void run() { @Override @SuppressWarnings("unchecked") - protected T getFrameworkProxy(final Class serviceType, final URL url) throws RpcException { + protected T doRefer(final Class serviceType, final URL url) throws RpcException { ClientProxyFactoryBean proxyFactoryBean = new ClientProxyFactoryBean(); proxyFactoryBean.setAddress(url.setProtocol("http").toIdentityString()); proxyFactoryBean.setServiceClass(serviceType); diff --git a/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java b/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java index 20cf8c460bac..68927d7bd1f7 100644 --- a/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java +++ b/dubbo-rpc/dubbo-rpc-xml/src/main/java/org/apache/dubbo/xml/rpc/protocol/xmlrpc/XmlRpcProtocol.java @@ -144,7 +144,7 @@ public void run() { } @SuppressWarnings("unchecked") - protected T getFrameworkProxy(final Class serviceType, URL url) throws RpcException { + protected T doRefer(final Class serviceType, URL url) throws RpcException { XmlRpcProxyFactoryBean xmlRpcProxyFactoryBean = new XmlRpcProxyFactoryBean(); xmlRpcProxyFactoryBean.setServiceUrl(url.setProtocol("http").toIdentityString()); xmlRpcProxyFactoryBean.setServiceInterface(serviceType); From fc797e2b5a024bcdcbc9417c8866040ecf7b8c6e Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Fri, 17 May 2019 17:07:46 +0800 Subject: [PATCH 24/26] remove unused imports after merge master --- .../support/MergeableClusterInvoker.java | 1 - .../remoting/exchange/ResponseCallback.java | 25 ---------------- .../com/alibaba/dubbo/rpc/RpcContext.java | 2 +- .../rpc/protocol/dubbo/FutureAdapter.java | 29 ------------------- .../alibaba/dubbo/rpc/support/RpcUtils.java | 5 ---- .../dubbo/monitor/dubbo/MetricsFilter.java | 3 +- .../exchange/support/DefaultFuture.java | 8 ----- .../dubbo/rpc/filter/CompatibleFilter.java | 3 +- .../dubbo/rpc/filter/GenericFilter.java | 5 ++-- .../dubbo/rpc/filter/GenericImplFilter.java | 1 + .../dubbo/rpc/protocol/AbstractInvoker.java | 2 -- .../rpc/proxy/InvokerInvocationHandler.java | 3 -- .../apache/dubbo/rpc/support/RpcUtils.java | 6 ++-- .../protocol/dubbo/ChannelWrappedInvoker.java | 3 +- .../dubbo/rpc/protocol/rmi/RmiProtocol.java | 2 -- .../rpc/protocol/thrift/ThriftProtocol.java | 3 +- 16 files changed, 13 insertions(+), 88 deletions(-) delete mode 100644 dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/exchange/ResponseCallback.java delete mode 100644 dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/FutureAdapter.java diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java index e9d53cd3162e..5ab90924cc6f 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java @@ -44,7 +44,6 @@ import java.util.concurrent.Executors; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; -import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.rpc.Constants.MERGER_KEY; /** diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/exchange/ResponseCallback.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/exchange/ResponseCallback.java deleted file mode 100644 index 893b262094b0..000000000000 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/remoting/exchange/ResponseCallback.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alibaba.dubbo.remoting.exchange; - -/** - * 2019-04-18 - */ -@Deprecated -public interface ResponseCallback extends org.apache.dubbo.remoting.exchange.ResponseCallback { -} diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java index bf6160c06acc..28ae5f1757a8 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/RpcContext.java @@ -29,7 +29,7 @@ private static RpcContext newInstance(org.apache.dubbo.rpc.RpcContext rpcContext RpcContext copy = new RpcContext(); copy.getAttachments().putAll(rpcContext.getAttachments()); copy.get().putAll(rpcContext.get()); - copy.setFuture(rpcContext.getFuture()); + copy.setFuture(rpcContext.getCompletableFuture()); copy.setUrls(rpcContext.getUrls()); copy.setUrl(rpcContext.getUrl()); copy.setMethodName(rpcContext.getMethodName()); diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/FutureAdapter.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/FutureAdapter.java deleted file mode 100644 index 07a69871af75..000000000000 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/protocol/dubbo/FutureAdapter.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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.alibaba.dubbo.rpc.protocol.dubbo; - -import org.apache.dubbo.remoting.exchange.ResponseFuture; - -/** - * 2019-04-18 - */ -public class FutureAdapter extends org.apache.dubbo.rpc.protocol.dubbo.FutureAdapter { - public FutureAdapter(ResponseFuture future) { - super(future); - } -} diff --git a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/support/RpcUtils.java b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/support/RpcUtils.java index 7f1ab98de5c4..d7db04fe106c 100644 --- a/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/support/RpcUtils.java +++ b/dubbo-compatible/src/main/java/com/alibaba/dubbo/rpc/support/RpcUtils.java @@ -20,7 +20,6 @@ import com.alibaba.dubbo.common.URL; import com.alibaba.dubbo.rpc.Invocation; -import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.Map; @@ -74,10 +73,6 @@ public static boolean isReturnTypeFuture(Invocation inv) { return org.apache.dubbo.rpc.support.RpcUtils.isReturnTypeFuture(inv); } - public static boolean hasFutureReturnType(Method method) { - return org.apache.dubbo.rpc.support.RpcUtils.hasFutureReturnType(method); - } - public static boolean isOneway(URL url, Invocation inv) { return org.apache.dubbo.rpc.support.RpcUtils.isOneway(url.getOriginalURL(), inv); } diff --git a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java index 9bbc8adf52a6..761de5945dc9 100644 --- a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java +++ b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java @@ -65,6 +65,7 @@ import static org.apache.dubbo.monitor.Constants.METRICS_PORT; import static org.apache.dubbo.monitor.Constants.METRICS_PROTOCOL; import static org.apache.dubbo.monitor.Constants.SERVICE; +import static org.apache.dubbo.remoting.Constants.EXECUTOR_SERVICE_COMPONENT_KEY; public class MetricsFilter implements Filter { @@ -177,7 +178,7 @@ private void setCompassQuantity(String groupName, String result, long duration, private List getThreadPoolMessage() { DataStore dataStore = ExtensionLoader.getExtensionLoader(DataStore.class).getDefaultExtension(); - Map executors = dataStore.get(Constants.EXECUTOR_SERVICE_COMPONENT_KEY); + Map executors = dataStore.get(EXECUTOR_SERVICE_COMPONENT_KEY); List threadPoolMtricList = new ArrayList<>(); for (Map.Entry entry : executors.entrySet()) { diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java index 72672885130e..1dab931a9c4a 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/support/DefaultFuture.java @@ -214,14 +214,6 @@ private void doSent() { sent = System.currentTimeMillis(); } - /** - * check time out of the future - */ - private static void timeoutCheck(DefaultFuture future) { - TimeoutCheckTask task = new TimeoutCheckTask(future); - TIME_OUT_TIMER.newTimeout(task, future.getTimeout(), TimeUnit.MILLISECONDS); - } - private String getTimeoutMessage(boolean scan) { long nowTimestamp = System.currentTimeMillis(); return (sent > 0 ? "Waiting server-side response timeout" : "Sending request timeout in client-side") diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java index bacdab6f6237..54aea0d73785 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/CompatibleFilter.java @@ -20,7 +20,6 @@ import org.apache.dubbo.common.logger.LoggerFactory; import org.apache.dubbo.common.utils.CompatibleTypeUtils; import org.apache.dubbo.common.utils.PojoUtils; -import org.apache.dubbo.remoting.Constants; import org.apache.dubbo.rpc.Filter; import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; @@ -31,7 +30,7 @@ import java.lang.reflect.Method; import java.lang.reflect.Type; -import static org.apache.dubbo.common.constants.RemotingConstants.SERIALIZATION_KEY; +import static org.apache.dubbo.remoting.Constants.SERIALIZATION_KEY; /** * CompatibleFilter make the remote method's return value compatible to invoker's version of object. diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java index 3c39c373ee78..fd83e1f4271b 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java @@ -43,10 +43,11 @@ import java.lang.reflect.Method; import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE; -import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_NATIVE_JAVA; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE_ASYNC; +import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_BEAN; +import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_NATIVE_JAVA; import static org.apache.dubbo.rpc.Constants.GENERIC_SERIALIZATION_PROTOBUF; -import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; /** * GenericInvokerFilter. diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java index b211c0e4faf1..ed5de7e1571d 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericImplFilter.java @@ -41,6 +41,7 @@ import java.lang.reflect.Type; import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE_ASYNC; import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; /** diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java index cd56fc774366..58cb4105f864 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/protocol/AbstractInvoker.java @@ -38,8 +38,6 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; -import static org.apache.dubbo.rpc.Constants.ASYNC_KEY; - /** * AbstractInvoker. */ diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java index 89b168a56be8..1d047cdccf42 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/proxy/InvokerInvocationHandler.java @@ -24,9 +24,6 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; -import static org.apache.dubbo.rpc.Constants.ASYNC_KEY; -import static org.apache.dubbo.rpc.Constants.FUTURE_RETURNTYPE_KEY; - /** * InvokerHandler */ diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java index 0894f34585db..7bf4533100e0 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/RpcUtils.java @@ -33,11 +33,11 @@ import java.util.concurrent.atomic.AtomicLong; import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE; -import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY; -import static org.apache.dubbo.rpc.Constants.ID_KEY; +import static org.apache.dubbo.common.constants.RpcConstants.$INVOKE_ASYNC; import static org.apache.dubbo.rpc.Constants.ASYNC_KEY; +import static org.apache.dubbo.rpc.Constants.AUTO_ATTACH_INVOCATIONID_KEY; import static org.apache.dubbo.rpc.Constants.FUTURE_GENERATED_KEY; -import static org.apache.dubbo.rpc.Constants.FUTURE_RETURNTYPE_KEY; +import static org.apache.dubbo.rpc.Constants.ID_KEY; import static org.apache.dubbo.rpc.Constants.RETURN_KEY; /** * RpcUtils diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java index 8b327334536d..101851240c00 100644 --- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java +++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/ChannelWrappedInvoker.java @@ -40,9 +40,8 @@ import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; import static org.apache.dubbo.common.constants.CommonConstants.TIMEOUT_KEY; import static org.apache.dubbo.remoting.Constants.SENT_KEY; -import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY; -import static org.apache.dubbo.rpc.Constants.ASYNC_KEY; import static org.apache.dubbo.rpc.Constants.TOKEN_KEY; +import static org.apache.dubbo.rpc.protocol.dubbo.Constants.CALLBACK_SERVICE_KEY; /** * Server push uses this Invoker to continuously push data to client. diff --git a/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java b/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java index d856f19bd804..d570b2f01f46 100644 --- a/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java +++ b/dubbo-rpc/dubbo-rpc-rmi/src/main/java/org/apache/dubbo/rpc/protocol/rmi/RmiProtocol.java @@ -36,8 +36,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.RELEASE_KEY; import static org.apache.dubbo.common.constants.RpcConstants.DUBBO_VERSION_KEY; import static org.apache.dubbo.rpc.Constants.GENERIC_KEY; -import static org.apache.dubbo.common.Version.isRelease263OrHigher; -import static org.apache.dubbo.common.Version.isRelease270OrHigher; /** * RmiProtocol. diff --git a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java index 332f3df20bb4..d6a88cbe4e46 100644 --- a/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java +++ b/dubbo-rpc/dubbo-rpc-thrift/src/main/java/org/apache/dubbo/rpc/protocol/thrift/ThriftProtocol.java @@ -46,9 +46,8 @@ import java.util.function.Function; import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY; -import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY; import static org.apache.dubbo.common.constants.RpcConstants.CONNECTIONS_KEY; -import static org.apache.dubbo.common.constants.RpcConstants.IS_SERVER_KEY; +import static org.apache.dubbo.rpc.Constants.IS_SERVER_KEY; /** * @since 2.7.0, use https://github.com/dubbo/dubbo-rpc-native-thrift instead From fa1c3731999f6d92cda7b999b30ca91de66feab7 Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 22 May 2019 16:32:56 +0800 Subject: [PATCH 25/26] Fix issues find during review. --- .../support/MergeableClusterInvoker.java | 6 +- .../dubbo/cache/filter/CacheFilter.java | 4 +- .../dubbo/remoting/exchange/Response.java | 61 ------------------- .../org/apache/dubbo/rpc/FutureContext.java | 4 +- 4 files changed, 9 insertions(+), 66 deletions(-) diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java index 5ab90924cc6f..d3243c4c0865 100644 --- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java +++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/support/MergeableClusterInvoker.java @@ -44,10 +44,10 @@ import java.util.concurrent.Executors; import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY; +import static org.apache.dubbo.rpc.Constants.ASYNC_KEY; import static org.apache.dubbo.rpc.Constants.MERGER_KEY; /** - * NOTICE! Does not work with async call. * @param */ @SuppressWarnings("unchecked") @@ -91,7 +91,9 @@ protected Result doInvoke(Invocation invocation, List> invokers, Load Map results = new HashMap<>(); for (final Invoker invoker : invokers) { - results.put(invoker.getUrl().getServiceKey(), invoker.invoke(new RpcInvocation(invocation, invoker))); + RpcInvocation subInvocation = new RpcInvocation(invocation, invoker); + subInvocation.setAttachment(ASYNC_KEY, "true"); + results.put(invoker.getUrl().getServiceKey(), invoker.invoke(subInvocation)); } Object result = null; diff --git a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java index 0d9d086cf077..772a16b5789e 100644 --- a/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java +++ b/dubbo-filter/dubbo-filter-cache/src/main/java/org/apache/dubbo/cache/filter/CacheFilter.java @@ -116,13 +116,13 @@ public Result invoke(Invoker invoker, Invocation invocation) throws RpcExcept /** * Cache value wrapper. */ - static class ValueWrapper implements Serializable{ + static class ValueWrapper implements Serializable { private static final long serialVersionUID = -1777337318019193256L; private final Object value; - public ValueWrapper(Object value){ + public ValueWrapper (Object value) { this.value = value; } diff --git a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java index b0453d61352c..568ecf1160b2 100644 --- a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java +++ b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/Response.java @@ -16,16 +16,6 @@ */ package org.apache.dubbo.remoting.exchange; -import org.apache.dubbo.remoting.Channel; -import org.apache.dubbo.remoting.Codec; -import org.apache.dubbo.remoting.Decodeable; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.util.HashMap; -import java.util.Map; - /** * Response */ @@ -183,55 +173,4 @@ public String toString() { return "Response [id=" + mId + ", version=" + mVersion + ", status=" + mStatus + ", event=" + mEvent + ", error=" + mErrorMsg + ", result=" + (mResult == this ? "this" : mResult) + "]"; } - - public static class AppResult { - - protected Map attachments = new HashMap(); - - protected Object result; - - protected Throwable exception; - - public Map getAttachments() { - return attachments; - } - - public void setAttachments(Map attachments) { - this.attachments = attachments; - } - - public Object getResult() { - return result; - } - - public void setResult(Object result) { - this.result = result; - } - - public Throwable getException() { - return exception; - } - - public void setException(Throwable exception) { - this.exception = exception; - } - } - - public static class DecodeableAppResult implements Codec, Decodeable { - - @Override - public void decode() throws Exception { - - } - - @Override - public void encode(Channel channel, OutputStream output, Object message) throws IOException { - - } - - @Override - public Object decode(Channel channel, InputStream input) throws IOException { - return null; - } - } } \ No newline at end of file diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java index 2468837958ce..8d5a1b62fa38 100644 --- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java +++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/FutureContext.java @@ -16,6 +16,8 @@ */ package org.apache.dubbo.rpc; +import org.apache.dubbo.common.threadlocal.InternalThreadLocal; + import java.util.concurrent.CompletableFuture; /** @@ -27,7 +29,7 @@ */ public class FutureContext { - public static ThreadLocal> futureTL = new ThreadLocal<>(); + public static InternalThreadLocal> futureTL = new InternalThreadLocal<>(); /** * get future. From b155d93a4a5cd2ad961b8c0cd9ec1d0bf5727a5f Mon Sep 17 00:00:00 2001 From: "ken.lj" Date: Wed, 22 May 2019 16:55:35 +0800 Subject: [PATCH 26/26] add UT --- .../dubbo/common/utils/ReflectUtilsTest.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java index f46235daaa1b..298f15c2f029 100644 --- a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java +++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/ReflectUtilsTest.java @@ -22,12 +22,14 @@ import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletableFuture; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -401,6 +403,32 @@ public void testForName2() { }); } + @Test + public void testGetReturnTypes () throws Exception{ + Class clazz = TypeClass.class; + + Type[] types = ReflectUtils.getReturnTypes(clazz.getMethod("getFuture")); + Assertions.assertEquals("java.lang.String", types[0].getTypeName()); + Assertions.assertEquals("java.lang.String", types[1].getTypeName()); + + Type[] types1 = ReflectUtils.getReturnTypes(clazz.getMethod("getString")); + Assertions.assertEquals("java.lang.String", types1[0].getTypeName()); + Assertions.assertEquals("java.lang.String", types1[1].getTypeName()); + + Type[] types2 = ReflectUtils.getReturnTypes(clazz.getMethod("getListFuture")); + Assertions.assertEquals("java.util.List", types2[0].getTypeName()); + Assertions.assertEquals("java.util.List", types2[1].getTypeName()); + } + + public static interface TypeClass { + + CompletableFuture getFuture(); + + String getString(); + + CompletableFuture> getListFuture(); + } + public static class EmptyClass { private EmptyProperty property; public boolean set;