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 像这种畸形文件名在“:”后面的直接被忽略,也就是说当成 *. ...
随机推荐
- jquery如何判断滚动条滚到页面底部并执行事件
首先理解三个dom元素,分别是:clientHeight.offsetHeight.scrollTop. clientHeight:这个元素的高度,占用整个空间的高度,所以,如果一个div有滚动条,那 ...
- django 内建标签和过滤器参考
下面的标签和过滤器参考就是为那些没有 admin 站点的可用的人准备的.由于 Django 是高度可定制的,你的 admin 里的关于标签和过滤器的参考可以认为是最可信的. 内建标签参考 block ...
- ARM内核和架构都是什么意思,它们到底是什么关系?
ARM产品越来越丰富,命名也越来越多.很多朋友提问: ARM内核和架构都是什么意思?内核和架构的关系是什么?比如ARMv7架构,这个架构指的是什么?小编选出了几个精彩回答!希望对嵌友们在选择设计电路时 ...
- SPSS时间序列分析
时间序列分析必须建立在预处理的基础上…… 今天看了一条新闻体会到了网络日志的重要性…… 指数平滑法(Exponential Smoothing,ES)是布朗(Robert G..Brown)所提出,布 ...
- firefox插件poster的使用,发起自定义http请求
快捷键:ctrl+alt+p 在开发WEB程序的时候,经常需要模拟http请求,接收服务器响应,从而检验程序的正确性. Firefox插件poster,可以模拟各种http请求,并详细设置请求参数,比 ...
- pstree命令
功能说明:以树状图显示运行的程序. 语法:pstree [-acGhlnpuUV][-H <程序识别码>][<程序识别码>/<用户名称>] 补充说明:pstree指 ...
- 什么是C#,.NET,ASP.NET?
C#,.NET,ASP.NET这三个词,对于大家并不陌生,最近花了点时间去了解了下.最终才发现我以前的理解有些偏差.现在分享给大家. 什么是C#? C#是微软公司发布的一种面向对象的.运行于 ...
- python:numpy(文件存取)
NumPy提供了多种存取数组内容的文件操作函数.保存数组数据的文件可以是二进制格式或者文本格式.二进制格式的文件又分为NumPy专用的格式化二进制类型和无格式类型. 一,tofile()和from ...
- linux下的type命令
type命令用来显示指定命令的类型.一个命令的类型可以是如下几种: alias 别名 keyword 关键字,Shell保留字 function 函数,Shell函数 builtin 内建命令,She ...
- html自定义提示框
自定义html提示框比较令人困惑的就是编写三角形的样式:以前的实现方式是在标签内使用span标签来实现.不过现在有了css提供的两个为类:before,:after之后,可以不用再内置span标签了: ...