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 dd68d7ef3dd..e9d090c4133 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 0f5378a19a0..061068a71b0 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 184a7b63df6..6b02731304a 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 82a0e8a2cb7..400a2c487a6 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 59303142d85..1628600a91f 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 b10fa01c802..0fce016fbf1 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 279160e7167..07e115d803b 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 c4cb85daf8b..74056f38a5b 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 413d9b9dc8a..8ab596bec1e 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 ad96a66830d..b745b0e1b26 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 9b6d2e88b73..6a706868bb9 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 ff29a6183a9..6a2e76e0474 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 b3d343a3bbe..aa27fabe458 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 8a4089c9049..a79a9facc09 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 c89a31421fa..3dc4a7c2aa9 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 c505326d0c3..874ab564a2e 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 ccec6875ca8..0c1a13dfe25 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 00000000000..30b81f0a67f --- /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 b96d14d1ee4..591af2c6203 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 a661b2b6b5b..22531301be1 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 ee1288affff..f77e0a523d0 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 148b5bce5f5..73706a087ba 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 4305ed6c05f..db6b7559a76 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 cb06537ae01..137fa23ead6 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 5e2ef2350d2..2f13a5c6714 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 1172c9be0fc..bd9c9287de7 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 90ed7c0b6a6..ad34442a436 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 6b5efc32f00..286b24b3f15 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 d0d315c9b4e..e95caa60444 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 4de9f5a170c..2f207b83b08 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 c64647309f0..217919f1d6f 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 2af761a0958..84950c395e1 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 cade5936402..b757536e9da 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 e6b90501264..06280ceaf25 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 10eb31e42fc..5358719e75e 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 01ba57dd7b8..730ab28e483 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 fa061b99696..7a4961bf954 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 f1341ef71f8..1afe0d550c8 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 fb288bb9643..1bbd4c25473 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 464452e1afe..a14371645fa 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 3922626fdfb..0e4917d200f 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 568ecf1160b..b0453d61352 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 9e641dd3579..00000000000 --- 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 290d668241a..3324ad994ac 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 95b95f4ce2f..00000000000 --- 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 4aef993a2e2..1666bbf38e7 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 3e57fba90c4..5b99079e0e1 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 6f342f997c0..d0f62fe6cb0 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 566bda10d8e..4478f86ecfd 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 413aa05b657..1989d3715c5 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 1ab41243dd4..2dd400545a4 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 3c11eca1c45..d08c8e4285d 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 987139275d5..6414434f51d 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 52c3e9d03e7..da93c18c646 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 03466bed688..267f5694065 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 9d2311fa5ff..9b8db0027c2 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 b898934c63c..00000000000 --- 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 00000000000..6ede9d4ee5b --- /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 b631dffe180..e48b7130159 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 a17fd906d55..7c634481d7e 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 00000000000..2468837958c --- /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 2b5f3dd9e95..058e0ad09c9 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 00000000000..a97a0be61f4 --- /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 37fe6cc6e34..622ef1f0309 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 58a258241ff..1ecd9dae771 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 fa63b7e4c1a..c585c178ce9 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 707bf3b77ad..207239d11ef 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 8087210f29a..00000000000 --- 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 98e42d94a38..00000000000 --- 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 1c2f69fecb9..fe692af565f 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 ace832ca33c..ad1a8a2492b 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 5db6b889d35..a2005e21e1a 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 fe85da0386a..df135a64894 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 cba9e7f4f46..7e3e5b8dda0 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 7715348f827..1cb9f87d488 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 b335a4141ff..c1b2eb5e6bc 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 ae7b92c40f1..5c86cae6577 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 6df1262fbef..f9caf44f069 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 c00689fc1c8..b6335823d8e 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 3df1f1d741e..58cb4105f86 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 814e9182280..a2a6ebb135f 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 a77a5bdc5f3..e03d3800984 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 00000000000..5c06b4e4d1d
--- /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 c5ed5943cd0..2106a4e0da8 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 6a562d6f6fd..aa813e1d1a5 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 3cdb65c742f..1d047cdccf4 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 07517d474a4..d93fa14930a 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 923c7cb0fd1..a7f973a832a 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 9237ab955c0..ecf7a4524f5 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 a5ae76133cf..ca55dfbe8ca 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 6d085f70617..9c749c983c5 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 b91c92d1640..e16dfbd8f61 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 a906af47be2..93635528338 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 c753c7e0e2e..506c10db5d5 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 02f367b8a8e..3befdc77df9 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 f40f8776e45..964e06ecb15 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 2fab7894e32..4cbc280275d 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 bd680e7502e..f2358ddaeca 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 43930ef6605..469632b9ec3 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 f99a0f35480..be853653335 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 fea5c300e07..5b86459624a 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 28baacbf611..7fec8d49fdb 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 5b7261de7b4..13a2ae244f4 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 eb944c9bc1a..1b74e6bc41b 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 5eb4dd9205f..0c92aea5bf5 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 4c78c1cceb9..5a22127d3ef 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 fac7c64a6ca..e6d3f84a781 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 4093eb266d6..40c6e2912d3 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 5f2c61b1cae..d8513a31806 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 77443016cfb..926a940cd5d 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 28645410d42..9fc47f6f9c9 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 f2bc4534fdc..c11ffca421d 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 faafe082852..cb589e228ec 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 98283f450c8..737e7390048 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 56fe5b8e564..3998026b70b 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 e2b71d05432..9a965cd80ea 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 7e9818d07f1..e37bd7d0dc9 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 2baa67ccae6..30ffda71fdf 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 b77e5e18b3c..3f2c0cf21d4 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 3b9239171a9..1eead54f164 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 0188a0fe329..7b99e2d80d5 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 1181e899d71..5a9bb845e15 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 8fa088bb95f..eef3bf6aa58 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 ba35c298ec4..38aeae826ea 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 6265254d4c6..09ba8c30aee 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 63e9fcdfff1..823d042142e 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 93a5900d753..75dd2d248df 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 fa123e232a5..e02fac3a176 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 055af6f8bb3..61c13ccce65 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 a1d5daadea8..1c781f85af2 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 ddb270def40..007f62beedc 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 90544aaf8a1..e33ae533f1c 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 e03d3800984..8cb59f55d0a 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 9c983a544a5..2fcace07a9a 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 aaba802cd4e..1708f092fb6 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 c869c60337b..16dd3c95825 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 061068a71b0..539686ed0e4 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 78369527efc..c353621056a 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 e48b7130159..789cbe74bdf 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 7c634481d7e..34454882904 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 fe692af565f..1fd0a8b9b33 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 ad1a8a2492b..2eb67b4df29 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 a2005e21e1a..794b6fdd987 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 df135a64894..1a8e40e4b87 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 1cb9f87d488..4fcf54008e4 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 c1b2eb5e6bc..8456a36ff7c 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 5c86cae6577..190f8a1fd2b 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 f9caf44f069..d6981e9aa55 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 b6335823d8e..c51cd3df427 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 e16dfbd8f61..709401d4278 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 964e06ecb15..49af0c0951e 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 f2358ddaeca..35fae848e33 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 75dd2d248df..0c835d2d951 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 1c781f85af2..9c1b1c4518c 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 22531301be1..07f5df9bf5a 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 00000000000..2db743d5716
--- /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 6ede9d4ee5b..16e938095a5 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 789cbe74bdf..e15053ac7fa 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 34454882904..53ad128efa7 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 1ecd9dae771..9c0c1ab50ca 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 2106a4e0da8..0ca8cede50d 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 aa813e1d1a5..fe42fb2c6be 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 49af0c0951e..bc9c1320372 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 469632b9ec3..aa3927971a3 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 1b74e6bc41b..57f1f1e6cc5 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 5a22127d3ef..17b2cca5671 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 d8513a31806..0f77d65d7a1 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 926a940cd5d..15b0bd2e0f3 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 9fc47f6f9c9..d00c5fa3f4a 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 e02fac3a176..6eb3c6a4378 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 61c13ccce65..e80d61c82ae 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 d00c5fa3f4a..03954d1b345 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 e15053ac7fa..2cb6cd9b23b 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 2cb6cd9b23b..9546e2a39ce 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 9c0c1ab50ca..7ad22c64cbb 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 7ad22c64cbb..1f3a5138319 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 527d5d5ff89..ea1e7409a77 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 db6b7559a76..4305ed6c05f 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 137fa23ead6..cb06537ae01 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 2f13a5c6714..5e2ef2350d2 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 bd9c9287de7..1172c9be0fc 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 ad34442a436..90ed7c0b6a6 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 286b24b3f15..6b5efc32f00 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 e95caa60444..d0d315c9b4e 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 30b81f0a67f..00000000000 --- 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 9e7302ff0ad..ce204728611 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 2f207b83b08..56ad1f0ec5f 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 5358719e75e..6ba5dfe84b4 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 7a2415fc216..9faccea3868 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 1fd0a8b9b33..4117002cb24 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 2eb67b4df29..895c008f664 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 794b6fdd987..43353f7e7dc 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 1a8e40e4b87..099357410bd 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 7e3e5b8dda0..e753f4d7804 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 4fcf54008e4..8f5411b179c 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 8456a36ff7c..e7622177876 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 d6981e9aa55..b104b2b4031 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 c51cd3df427..31b0dc977a8 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 247409ed8d4..58cb4105f86 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 85297812ebd..4cd13bd17f5 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 737e7390048..7b1c17c7517 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 524cd1a706b..bcc3cf9ec8a 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 c1d9e4e727b..b162030fd8d 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 0d8ca6728c7..290f5b4df52 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 06cea8c1dc2..1d047cdccf4 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 fe1608d3c94..593f7033e44 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 481fb52de48..8693e508add 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 ec2d578ba1d..5b0c4e5dc36 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 a46b12d3e82..3455b7cf1f2 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 cf34c8c42d2..1452313b9cf 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 c62bd8c85b8..20cf8c460ba 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 c03a063ed0d..64f005876e2 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 1271d86972a..cb3b699f807 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 ecf7a4524f5..46089968172 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 5b0c4e5dc36..c42ffd9070b 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 488b55d6179..fff02a69126 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 dac73c68feb..bc8e4d6c5e7 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 3455b7cf1f2..a1a4053308a 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 70e5a19be2d..47a9189e54b 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 1708f092fb6..aaba802cd4e 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 66e97c3c965..b056a795ee9 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 16dd3c95825..028d3cf42e2 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 cbe619c6ea3..b4f40061046 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 40b8f04a518..af72a465665 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 8fd653a7a33..8a7975c8fe5 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 d2cbfacad68..1116651b9ee 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 bc93d993c31..928b01c45ff 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 20cf8c460ba..68927d7bd1f 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 e9d53cd3162..5ab90924cc6 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 893b262094b..00000000000 --- 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 bf6160c06ac..28ae5f1757a 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 07a69871af7..00000000000 --- 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 7f1ab98de5c..d7db04fe106 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 9bbc8adf52a..761de5945dc 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 72672885130..1dab931a9c4 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 bacdab6f623..54aea0d7378 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 3c39c373ee7..fd83e1f4271 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 b211c0e4faf..ed5de7e1571 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 cd56fc77436..58cb4105f86 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 89b168a56be..1d047cdccf4 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 0894f34585d..7bf4533100e 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 8b327334536..101851240c0 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 d856f19bd80..d570b2f01f4 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 332f3df20bb..d6a88cbe4e4 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 5ab90924cc6..d3243c4c086 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 0d9d086cf07..772a16b5789 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 b0453d61352..568ecf1160b 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 2468837958c..8d5a1b62fa3 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 f46235daaa1..298f15c2f02 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;