apache dubbo 2.7.3 源代码片段 - 使用CompletableFuture

 

package cn.java.dubbo.demo.internal;

import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.utils.StringUtils;
import org.apache.dubbo.remoting.Channel;
import org.apache.dubbo.remoting.RemotingException;
import org.apache.dubbo.remoting.exchange.ExchangeChannel;
import org.apache.dubbo.remoting.exchange.Request;
import org.apache.dubbo.rpc.*;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.function.Function;

/**
 */
@Slf4j
public class CompletableFutureTest {
    public static void main(String[] args) {
        (new Server()).doRun(args);

        {
            CompletableFutureInternal completableFutureInternal = new CompletableFutureInternal();
            completableFutureInternal.doDemo0();
            completableFutureInternal.doDemo1();
        }
    }

    static class Server {
        private static FooOneServiceImpl fooOneServiceImpl = new FooOneServiceImpl();

        public void doRun(String[] args) {
            HeaderExchangeHandler handler = new HeaderExchangeHandler();
            try {
                handler.received(null, null, fooOneServiceImpl.getClass().getMethod("sayHello", String.class));
            } catch (java.lang.Exception ex) {
                log.error("sayHello", ex);
            }

            try {
                handler.received(null, null, fooOneServiceImpl.getClass().getMethod("doThrowRpcException", String.class));
            } catch (java.lang.Exception ex) {
                log.error("doThrowRpcException", ex);
            }

            try {
                handler.received(null, null, fooOneServiceImpl.getClass().getMethod("doThrowException", String.class));
            } catch (java.lang.Exception ex) {
                log.error("doThrowException", ex);
            }

        }

        static class HeaderExchangeHandler {
            /**
             * @see org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler#received(org.apache.dubbo.remoting.Channel, java.lang.Object)
             */
            public void received(Channel channel, Object message, Method method) throws RemotingException {
                Request request = (Request) message;
                handleRequest(null, request, method);
            }

            /**
             * @see org.apache.dubbo.remoting.exchange.support.header.HeaderExchangeHandler# handleRequest(org.apache.dubbo.remoting.exchange.ExchangeChannel, org.apache.dubbo.remoting.exchange.Request)
             */
            void handleRequest(final ExchangeChannel channel, Request req, Method method) throws RemotingException {
                // Response res = new Response(req.getId(), req.getVersion());

                try {
                    // invoke dubboProtocol requestHandler
                    CompletableFuture<Object> future = reply(method);

                    future.whenComplete((appResult, ex) -> {
                        try {
                            if (ex == null) {
                                // res.setStatus(Response.OK);
                                // res.setResult(appResult);
                                log.info("appResult = {}", appResult); // 业务数据、业务方法抛出的异常
                            } else { // 框出现异常
                                // res.setStatus(Response.SERVICE_ERROR);
                                // res.setErrorMessage(StringUtils.toString(t));
                                log.error("error", ex);
                            }
                            // channel.send(res); // 发送数据到客户端

                            if (false) {
                                throw new RemotingException(null, "xxx");
                            }
                        } catch (RemotingException e) {
                            log.warn("Send result to consumer failed, channel is channel, msg is " + e);
                        } finally {
                            log.info("channel 发送数据 finally");
                        }
                    });
                } catch (Throwable ex) {
                    String exStr = StringUtils.toString(ex);
                    log.error("handleRequest 调用 reply 出现异常, exStr = {}", exStr, ex);

                    // res.setStatus(Response.SERVICE_ERROR);
                    // res.setErrorMessage(StringUtils.toString(ex));
                    // channel.send(res); // 发送数据到客户端
                }
            }
        }


        /**
         * @see org.apache.dubbo.rpc.protocol.dubbo.DubboProtocol# requestHandler
         */
        static CompletableFuture<Object> reply(Method method) {
            AbstractProxyInvoker invoke = new AbstractProxyInvoker();
            Result result = invoke.invoke(method);

            return result.completionFuture().thenApply(Function.identity());
        }


        /**
         * @see org.apache.dubbo.rpc.proxy.jdk.JdkProxyFactory#getInvoker(java.lang.Object, java.lang.Class, org.apache.dubbo.common.URL)
         */
        static class AbstractProxyInvoker {

            Invocation mockInvocation(Method method) {
                RpcInvocation invocation = new RpcInvocation();
                invocation.setMethodName(method.getName());
                return invocation;
            }

            /**
             * @see org.apache.dubbo.rpc.proxy.AbstractProxyInvoker#invoke(org.apache.dubbo.rpc.Invocation)
             */
            public Result invoke(Method method) throws RpcException {
                Invocation invocation = mockInvocation(method);

                try {
                    Object value = doInvoke(method);
                    CompletableFuture<Object> future = wrapWithFuture(value, invocation); // Future 模式
                    AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation);
                    future.whenComplete((obj, ex) -> {
                        AppResponse result = new AppResponse();

                        if (ex != null) { // 存在异常
                            if (ex instanceof CompletionException) {
                                result.setException(ex.getCause());
                            } else {
                                result.setException(ex);
                            }
                        } else { // 无异常
                            result.setValue(obj);
                        }

                        asyncRpcResult.complete(result);
                    });
                    return asyncRpcResult;
                } catch (InvocationTargetException e) { // 反射调用异常
                    if (RpcContext.getContext().isAsyncStarted() && !RpcContext.getContext().stopAsync()) {
                        log.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 AsyncRpcResult.newDefaultAsyncResult(null, e.getTargetException(), invocation); // 异常数据
                } catch (Throwable e) { // 捕获取服务端的《所有异常》
                    throw new RpcException("Failed to invoke remote proxy method " + invocation.getMethodName() + " to xxx, cause: " + e.getMessage(), e);
                }

            }

            protected Object doInvoke(Method method) throws Throwable {
                return method.invoke(fooOneServiceImpl, "");
            }

            private CompletableFuture<Object> wrapWithFuture(Object value, Invocation invocation) {
                if (RpcContext.getContext().isAsyncStarted()) {
                    return ((AsyncContextImpl) (RpcContext.getContext().getAsyncContext())).getInternalFuture();
                } else if (value instanceof CompletableFuture) {
                    return (CompletableFuture<Object>) value;
                }

                return CompletableFuture.completedFuture(value);
            }
        }
    }

    static class FooOneServiceImpl {
        public String sayHello(String name) {
            return "hi, " + name;
        }

        public String doThrowRpcException(String name) throws RpcException {
            throw new RpcException(RpcException.BIZ_EXCEPTION, "user is not login.");
        }

        public String doThrowException(String name) throws java.lang.Exception {
            throw new java.lang.Exception("user is not login.");
        }
    }

    static class CompletableFutureInternal {

        private AsyncRpcResult getAsyncRpcResult() {
            RpcInvocation invocation = new RpcInvocation();
            invocation.setMethodName("method0");
            AsyncRpcResult asyncRpcResult = new AsyncRpcResult(invocation);
            return asyncRpcResult;
        }

        public void doDemo0() {
            // 异步结果
            AsyncRpcResult asyncRpcResult = getAsyncRpcResult();

            // 调用方法
            {
                Object value = "this is result.";
                CompletableFuture<Object> future = CompletableFuture.completedFuture(value);
                future.whenComplete((obj, ex) -> {
                    AppResponse result = new AppResponse();
                    if (ex != null) { // 存在异常
                        if (ex instanceof CompletionException) {
                            result.setException(ex.getCause());
                        } else {
                            result.setException(ex);
                        }
                    } else { // 无异常
                        result.setValue(obj);
                    }

                    asyncRpcResult.complete(result);
                });
            }

            // 处理异步执行结果
            {
                CompletableFuture<Object> future = asyncRpcResult.completionFuture().thenApply(Function.identity());
                future.whenComplete((appResult, ex) -> {
                    if (ex == null) {
                        log.info("appResult = {}", appResult); // 业务数据、业务方法抛出的异常
                    } else { // 框出现异常
                        log.error("error", ex);
                    }
                    // channel.send(res); // 发送数据到客户端
                });
            }
        }

        public void doDemo1() {
            doDemo1Common("complete");
            doDemo1Common("completeExceptionally");
        }

        private void doDemo1Common(Object value) {
            CompletableFuture asyncRpcResult = new CompletableFuture();

            {
                CompletableFuture<Object> future = CompletableFuture.completedFuture(value);
                future.whenComplete((obj, ex) -> {
                    if ("completeExceptionally".equals(value)) {
                        asyncRpcResult.completeExceptionally(new Exception("throw exception for " + value));
                    } else {
                        asyncRpcResult.complete(obj);
                    }
                });
            }

            {
                asyncRpcResult.whenComplete((appResult, ex) -> {
                    if (ex == null) {
                        log.info("appResult = {}", appResult); // 业务数据、业务方法抛出的异常
                    } else { // 框出现异常
                        log.error("happen exception", ex);
                    }
                    // channel.send(res); // 发送数据到客户端
                });
            }
        }
    }
}

 

 

 

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值