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对象,取得保存在其中的信息进行处理,这是典型的【黑板报】设计模式。

时间: 2024-10-08 09:03:32

libthrift0.9.0解析(四)之TThreadPoolServer&ServerContext的相关文章

libthrift0.9.0解析(五)之TNonblockingServer&THsHaServer

本文是一边看代码一边写的,是真随笔,随看随下笔. 看TNonblockingServer,先看其父类AbstractNonblockingServer.一般来说,父类封装的都是通用的东西,具体的底层实现方式交由子类来实现.因此抽象类一般会作为两层之间的交点所在,父类在上层,子类在下层.先看父类,再看子类,先看高层,再看低层,先看框架再忽略底层细节,遇到一些细节非常想看想深入进去时,也会忍住不看,待到上层了解完毕之后,再回过头来看.必要先在头脑中形成一个坐标系,然后再往其中安放具体物件.不知这样对

libthrift0.9.0 解析-Server

TServer 属性serverTransport 为TServerTransport类型,类图如下: 构造函数,简单根据args设置几个成员,大部分是工厂类: protected TServer(AbstractServerArgs args) { processorFactory_ = args.processorFactory; // 处理器工厂 serverTransport_ = args.serverTransport; // 服务器transport,具有listen和accept

马程序员学习笔记——红黑树解析四

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 本篇是将上面三篇的理论知识转化成代码,java实现 首先,看一下算法导论里的伪代码 一.左旋 The pseudocode for LEFT-ROTATE assumes that right[x] ≠ nil[T] and that the root's parent is nil[T].(伪代码的左旋方法中假设X的右孩子不为空) LEFT-

Android Volley完全解析(四),带你从源码的角度理解Volley

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17656437 经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了,但是对于Volley的工作原理,恐怕有很多朋友还不是很清楚.因此,本篇文章中我们就来一起阅读一下Volley的源码,将它的工作流程整体地梳理一遍.同时,这也是Volley系列的最后一篇文章了. 其实,Volley的官方文档中本身就附有了一张Volley的工作流程图,如下图所示. 多数朋友突然看到一张这样

Spring 源码解析之ViewResolver源码解析(四)

Spring 源码解析之ViewResolver源码解析(四) 1 ViewResolver类功能解析 1.1 ViewResolver Interface to be implemented by objects that can resolve views by name. View state doesn't change during the running of the application, so implementations are free to cache views. I

Android Bitmap 全面解析(四)图片处理效果对比 ...

对比对象: UIL Volley 官方教程中的方法(此系列教程一里介绍的,ImageLoader的处理方法和官方的差不多) ------------------------------------------------------------------------ 首先单张图片的压缩处理,也是分析重点 专门撸了一个小demo(结尾会放出下载连接)将对应计算方法copy了出来,然后计算了几十组数据,进行了对比 原图宽高都是一个10000以内的随机整数,限定大小是400 200,然后进行压缩处理

Android 百度地图 SDK v3.0.0 (四) 引入离线地图功能

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37758097 一直觉得地图应用支持离线地图很重要啊,我等移动2G屌丝,流量不易,且用且珍惜. 对于官方开发指南对于离线地图的教程,提供了两种方案: 第一,手动导入,先将从官网下载的离线包解压,把vmp文件夹拷入SD卡根目录下的BaiduMapSDK文件夹内.好吧,我表示不能接受,无视了. 第二,接口下载方法如下:mOffline.start(cityid);还比较靠谱,就是没详

c# 轻量级 ORM 框架 之 Model解析 (四)

关于orm框架设计,还有必要说的或许就是Model解析了,也是重要的一个环节,在实现上还是相对比较简单的. Model解析,主要用到的技术是反射了,即:把类的属性与表的字段做映射. 把自己的设计及实现思路写出来也希望能有人给很好的优化建议,同时也给新手一点启发吧. 首先先给Model属性定义特性,先普及一下"特性"的概念和为什么用特性(Attribute). 简单来说,特性是给一个类,或方法,或属性 打上一个标记(或者叫附加信息),具体理解还是看例子比较好吧, 在做类与表之间映射时,我

Packet Tracer 5.0实验(四) 利用三层交换机实现VLAN间路由

Packet Tracer 5.0实验(四) 利用三层交换机实现VLAN间路由 一.实验目标 掌握交换机Tag VLAN 的配置: 掌握三层交换机基本配置方法: 掌握三层交换机VLAN路由的配置方法: 通过三层交换机实现VLAN间相互通信: 二.实验背景 某企业有两个主要部门,技术部和销售部,分处于不同的办公室,为了安全和便于管理,对两个 部门的主机进行了VLAN的划分,技术部和销售部分处于不同的VLAN.现由于业务的需求,需要销售部和技术部的主机能够相互访问,获得相应的资源,两个 部门的交换机