当前位置: 首页 > news >正文

RpcContext

RpcContext内部有一个ThreadLocal变量,它是作为ThreadLocalMap的key,表明每个线程有一个RpcContext。

public class RpcContext {
    private static final ThreadLocal<RpcContext> LOCAL = new ThreadLocal<RpcContext>() {
        @Override
        protected RpcContext initialValue() {
            return new RpcContext();
        }
    };

    //如果get在set之前,则get会返回initialValue()创建的对象
    public static RpcContext getContext() {
        return LOCAL.get();
    }
}

1. RpcContext的一种用法是:存放Future。Future封装了consumer的请求和响应,发送请求时会创建Future对象,此时响应是null,而DubboClientHandler线程会设置响应值。

设置调用方式为异步:

<dubbo:service interface="com.zhang.HelloService" ref="helloServiceImpl" protocol="dubbo">
    <dubbo:method name="sayHello" retries="0" async="true"></dubbo:method>
</dubbo:service>

RpcContext设置Future:

//DubboInvoker
protected Result doInvoke(final Invocation invocation) throws Throwable {
    RpcInvocation inv = (RpcInvocation) invocation;
    final String methodName = RpcUtils.getMethodName(invocation);
    inv.setAttachment(Constants.PATH_KEY, getUrl().getPath());
    inv.setAttachment(Constants.VERSION_KEY, version);
    
    ExchangeClient currentClient;
    if (clients.length == 1) {
        currentClient = clients[0];
    } else {
        currentClient = clients[index.getAndIncrement() % clients.length];
    }
    try {
        boolean isAsync = RpcUtils.isAsync(getUrl(), invocation);
        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) { //异步调用,设置Future ResponseFuture future = currentClient.request(inv, timeout) ; RpcContext.getContext().setFuture(new FutureAdapter<Object>(future)); return new RpcResult(); } else { RpcContext.getContext().setFuture(null); return (Result) currentClient.request(inv, timeout).get(); } } catch (TimeoutException e) { } catch (RemotingException e) { } }

调用时直接返回:

HelloService helloService = (HelloService) appCtx.getBean("hello");
//返回null
String str = helloService.sayHello();

Future<String> future = RpcContext.getContext().getFuture();
//阻塞获取结果
String str2 = future.get();

 

转载于:https://www.cnblogs.com/allenwas3/p/8384206.html

相关文章:

  • mysql学习笔记(1)--varChar和char类型的区别
  • etcd raft library
  • jQuery数组去重复
  • Nginx 配置文件重写
  • python------并发编程
  • freebsd安装python2
  • js为什么是单线程的?10分钟了解js引擎的执行机制
  • 鸟哥的linux私房菜学习-(十)vim程序编辑器
  • Linux上vi编辑文件非正常退出后文件恢复
  • 常用网络技术
  • javascript脚本混淆
  • gf框架之grpool - 高性能的goroutine池
  • 谷歌浏览器如何调试JS
  • CocosCreator引擎修改与定制
  • 新年的展望,2018 hello world~
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 【面试系列】之二:关于js原型
  • bearychat的java client
  • Github访问慢解决办法
  • HTTP 简介
  • JavaScript新鲜事·第5期
  • js如何打印object对象
  • SQL 难点解决:记录的引用
  • 从@property说起(二)当我们写下@property (nonatomic, weak) id obj时,我们究竟写了什么...
  • 关于List、List?、ListObject的区别
  • 关于字符编码你应该知道的事情
  • 技术发展面试
  • 京东美团研发面经
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 驱动程序原理
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 使用 Xcode 的 Target 区分开发和生产环境
  • 树莓派 - 使用须知
  • 为什么要用IPython/Jupyter?
  • 一个完整Java Web项目背后的密码
  • 正则学习笔记
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 仓管云——企业云erp功能有哪些?
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • #QT(TCP网络编程-服务端)
  • #QT项目实战(天气预报)
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (C++20) consteval立即函数
  • (附源码)ssm本科教学合格评估管理系统 毕业设计 180916
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (转)Android学习系列(31)--App自动化之使用Ant编译项目多渠道打包
  • (转)nsfocus-绿盟科技笔试题目
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)四层和七层负载均衡的区别
  • .bat批处理(一):@echo off
  • .NET 2.0中新增的一些TryGet,TryParse等方法
  • .NET CLR Hosting 简介
  • .NET 中创建支持集合初始化器的类型
  • [ IOS ] iOS-控制器View的创建和生命周期