libthrift0.9.0解析(四)之TThreadPoolServer&ServerContext
TThreadPoolServer直接继承自TServer,实现类serve和stop操作。
在serve中可以接受多个连接,每个连接单独开一个线程进行处理,在每个线程中,按顺序处理该线程所绑定连接的请求,因此对同一个连接来说,是同步的。
serve函数主要代码:
while (!stopped_) {
int failureCount = 0;
try {
TTransport client = serverTransport_.accept();
WorkerProcess wp = new WorkerProcess(client);
executorService_.execute(wp);
} catch (TTransportException ttx) {
if (!stopped_) {
++failureCount;
LOGGER.warn("Transport error occurred during acceptance of message.", ttx);
}
}
}
其中线程池以及最大线程数通过ThreadPoolExecutor类来实现。
在每个WorkerProcess中,处理请求关键代码如下:
public void run() {
TProcessor processor = null;
TTransport inputTransport = null;
TTransport outputTransport = null;
TProtocol inputProtocol = null;
TProtocol outputProtocol = null;
TServerEventHandler eventHandler = null;
ServerContext connectionContext = null;
try {
processor = processorFactory_.getProcessor(client_);
inputTransport = inputTransportFactory_.getTransport(client_);
outputTransport = outputTransportFactory_.getTransport(client_);
inputProtocol = inputProtocolFactory_.getProtocol(inputTransport);
outputProtocol = outputProtocolFactory_.getProtocol(outputTransport);
eventHandler = getEventHandler();
if (eventHandler != null) {
connectionContext = eventHandler.createContext(inputProtocol, outputProtocol);
}
// we check stopped_ first to make sure we're not supposed to be shutting
// down. this is necessary for graceful shutdown.
while (true) {
if (eventHandler != null) {
eventHandler.processContext(connectionContext, inputTransport, outputTransport);
}
if(stopped_ || !processor.process(inputProtocol, outputProtocol)) {
break;
}
}
} catch (TTransportException ttx) {
// Assume the client died and continue silently
} catch (TException tx) {
LOGGER.error("Thrift error occurred during processing of message.", tx);
} catch (Exception x) {
LOGGER.error("Error occurred during processing of message.", x);
}
if (eventHandler != null) {
eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol);
}
if (inputTransport != null) {
inputTransport.close();
}
if (outputTransport != null) {
outputTransport.close();
}
}
注意一下类型为ServerContext的connectionContext变量的生命周期以及角色:
1)在处理所有请求之前,通过eventHandler.createContext(inputProtocol, outputProtocol)创建;
2)在处理每个请求前,通过eventHandler.processContext(connectionContext, inputTransport, outputTransport)进行处理;
3)在停止处理时,通过eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol) 释放相关资源,生命宣告停止。
使用者可以通过eventHandler插入自己的代码。
【Tips】
根据上面对connectionContext生命周期的分析,我们可以自己实现TServerEventHandler接口,然后在实现类中保存ServerContext信息以及其它附属信息,因为TServerEventHandler可以访问传输层级别,因此可以在其中保存一些连接的底层信息,比如客户端ip,端口等;在processContext函数中,可以更新每次请求前的临时信息供该次请求使用,这样,在我们的IDL中定义的实现函数中,可以访问TServerEventHandler对象,取得保存在其中的信息进行处理,这是典型的【黑板报】设计模式。
libthrift0.9.0解析(四)之TThreadPoolServer&ServerContext的更多相关文章
- libthrift0.9.0解析(三)之TProtocol&TTransport
以上是transport和protocol的类图和结构图. transport封装了底层的传输通道,主要有read/write.open/close等基本的读写方法,而且都是对于二进制数据. p ...
- libthrift0.9.0解析(二)之TSimpleServer
TSimpleServer简单实现Tserver,代码如下. /** * Simple singlethreaded server for testing. * */ public class TSi ...
- libthrift0.9.0解析(五)之TNonblockingServer&THsHaServer
本文是一边看代码一边写的,是真随笔,随看随下笔. 看TNonblockingServer,先看其父类AbstractNonblockingServer.一般来说,父类封装的都是通用的东西,具体的底层实 ...
- libthrift0.9.0解析(一)之TServer
TServer 属性serverTransport 为TServerTransport类型,类图如下: 构造函数,简单根据args设置几个成员,大部分是工厂类: protected TServer(A ...
- Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素
Fixflow引擎解析(四)(模型) - 通过EMF扩展BPMN2.0元素 Fixflow引擎解析(三)(模型) - 创建EMF模型来读写XML文件 Fixflow引擎解析(二)(模型) - BPMN ...
- Sentinel源码解析四(流控策略和流控效果)
引言 在分析Sentinel的上一篇文章中,我们知道了它是基于滑动窗口做的流量统计,那么在当我们能够根据流量统计算法拿到流量的实时数据后,下一步要做的事情自然就是基于这些数据做流控.在介绍Sentin ...
- Android Bitmap 全面解析(四)图片处理效果对比 ...
对比对象: UIL Volley 官方教程中的方法(此系列教程一里介绍的,ImageLoader的处理方法和官方的差不多) -------------------------------------- ...
- 悟透Javascript undefined,null,"",0这四个值转换为逻辑值时就是false &this关键字
话题一:undefined,null,"",0这四个值转换为逻辑值时就是false 也就是在if判断时会把上面的五个作为false来判断.但是它们的类型确是不尽相同的,如下所示. ...
- IIS6.0解析漏洞
IIS6.0解析漏洞分两种 1.目录解析 以*.asp命名的文件夹里的文件都将会被当成ASP文件执行. 2.文件解析 *.asp;.jpg 像这种畸形文件名在“:”后面的直接被忽略,也就是说当成 *. ...
随机推荐
- JDBC驱动汇总
Microsoft SQL Server (6.5, 7, 2000 and 2005) and Sybase (10, 11, 12). ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
- JQuery Dialog(JS模态窗口,可拖拽的DIV) 效果实现代码
效果图 调用示意图 交互示意图 如上图所示,这基本是JQueryDialog的完整逻辑流程了. 1.用户点击模态窗口的“提交”按钮时,调用JQueryDialog.Ok()函数,这个函数对应了用户 ...
- select查询的性能
为什么忘记commit也会造成select查询的性能问题 今天遇到一个很有意思的问题,一个开发人员反馈在测试服务器ORACLE数据库执行的一条简单SQL语句非常缓慢,他写的一个SQL没有返回任何数据, ...
- Linux的时钟管理
本文转自博客园zhenwenxian的Linux时间管理,很详细,写得很不错,对初学者还是有很大帮助的. 时间管理在内核中占有非常重要的地位.相对于事件驱动,内核中有大量的函数都是基于时间驱动的.内核 ...
- Web分析日志
http://www.docin.com/p-649515490.html http://wenku.baidu.com/link?url=kB-83fbl1Zc3Y6U2BYLj-lKMWShe8Z ...
- 转一篇:Hyper-V和VMware的高可用实时迁移技术详解
ESX里以集群的ha.drs.dpm功能实现 HYPER-V里以集群+共享存储实现. ~~~~~~~~~~ 微软公司的Hyper-V虚拟化管理程序一经面世就引发了业界的普遍关注.本文意在对Hyper- ...
- MVC与三层架构的区别
我们平时总是将三层架构与MVC混为一谈,殊不知它俩并不是一个概念.下面我来为大家揭晓我所知道的一些真相. 首先,它俩根本不是一个概念. 三层架构是一个分层式的软件体系架构设计,它可适用于任何一个项目. ...
- tree .git
$ tree .git .git ├── branches ├── config ├── description ├── FETCH_HEAD ├── gitk.cache ├── HEAD ├── ...
- POJ2251 Dungeon Master(bfs)
题目链接. 题目大意: 三维迷宫,搜索从s到e的最小步骤数. 分析: #include <iostream> #include <cstdio> #include <cs ...
- Sql自动生成字母加数字的随机数
/* select char(65+ceiling(rand()*25)) --随机字母(大写) select char(97+ceiling(rand()*25)) --随机字母(小写) selec ...