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 像这种畸形文件名在“:”后面的直接被忽略,也就是说当成 *. ...
随机推荐
- .net FrameWork4.0安装未成功
安装了一上午的.net framework 4.0,各种失败,查了好多答案,各种不靠谱,最后终于找到答案了 和Windows Update有关系,给目录名重命名一下再次安装,即安装成功了! 下载地址: ...
- Lua:简单入门
首先,感谢 runoob.com:http://www.runoob.com/lua/lua-tutorial.html 直接用 SciTE 进行文本编辑,F5调试,非常方便. 注意点: 1. 变量的 ...
- zoj 3787 Access System
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5274 #include <cstdio> #include < ...
- LINUX下中文语言包的安装(转)
在安装盘上已经有各种语言包了,我们只需要找到他们,并安装就可以了.中文的是fonts-chinese-3.02-9.6.el5.noarch.rpmfonts-ISO8859-2-75dpi-1.0- ...
- 双向队列 STL
题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操作.现在给你一系列的操作,请输出最后队列的状态:命令格式:LIN X X表示一个整数,命 ...
- Types of AOP
There are two distinct types of AOP: static and dynamic. The difference between them is really the p ...
- php开启错误提示
1.在php.ini文件里加上下面两句 display_errors = Onerror_reporting = E_ALL | E_STRICT 2.在Apache的 httpd.conf文件里加上 ...
- HTTP学习实验8-windows添加telnet功能
Windows 添加telnet功能: 控制面板->(查看方式:小图标)->程序和功能->打开或关闭Windows功能->Telnet客户端 Telnet 设置: 打开cmd, ...
- MD5方法代码(生成小写的md5) C#版本
public string GetMD5Str(string input) { // Use input string to calculate MD5 hash MD5 md5 = System.S ...
- Java多线程编程(一)
1.Java创建多线程的方法一:(1)实现Runnable接口并实现其中的run()方法:(2)将Runable对象提交给一个Thread构造器,调用start()方法. [程序实例]单线程 publ ...